Cod sursa(job #178985)

Utilizator razvi9Jurca Razvan razvi9 Data 15 aprilie 2008 14:02:16
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.64 kb
#include<cstdio>
#include<cstring>
const int inf=0x7fffffff;
const int baza=10000;
int n,m,a[1001][1001],viz[1001][1001],l[1000001],st,dr,i,j,inc,fin,max;
char s[baza];
inline void go(int i,int j,int x)
{
	if(i<1 || j<1 || i>n || j>m) return;
	if(a[i][j]<=x+1) return;
	a[i][j]=x+1;
	l[++dr]=i*baza+j;
	if(x+1>max) max=x+1;
}
inline void bf()
{
	st=1;
	while(st<=dr)
	{
		i=l[st]/baza;
		j=l[st]%baza;
		go(i-1,j,a[i][j]);
		go(i+1,j,a[i][j]);
		go(i,j+1,a[i][j]);
		go(i,j-1,a[i][j]);
		st++;
	}
}
inline int go2(int i,int j,int k)
{
	if(i<1 || j<1 || i>n || j>m) return 0;
	if(a[i][j]<k) return 0;
	if(viz[i][j]) return 0;
	l[++dr]=i*baza+j;
	viz[i][j]=1;
	return l[dr]==fin;
}
inline int good(int k)
{
	st=1;dr=1;
	memset(viz,0,sizeof(viz));
	l[st]=inc;
	while(st<=dr)
	{
		i=l[st]/baza;
		j=l[st]%baza;
		if(go2(i-1,j,k)) return 1;
		if(go2(i+1,j,k)) return 1;
		if(go2(i,j-1,k)) return 1;
		if(go2(i,j+1,k)) return 1;
		st++;
	}
	return 0;
}
inline int seek(int s,int d)
{
	if(d==0) return -1;
	int m;
	while(s<d)
	{
		m=(s+d+1)>>1;
		if(good(m)) s=m;
		else
			d=m-1;
	}
	if(good(s)) 
		return s;
	return -1;
}
int main()
{
	freopen("barbar.in","r",stdin);
	freopen("barbar.out","w",stdout);
	scanf("%d %d ",&n,&m);
	for(i=1;i<=n;i++)
	{
		gets(s);
		for(j=1;j<=m;j++)
			switch(s[j-1])
			{
			case 'D':l[++dr]=i*baza+j;a[i][j]=0;	break;
			case 'I':inc=i*baza+j;a[i][j]=inf;break;
			case 'O':fin=i*baza+j;a[i][j]=inf;break;
			case '*':a[i][j]=-1;break;
			case '.':a[i][j]=inf;break;
			}
	}
	bf();
	printf("%d\n",seek(1,a[inc/baza][inc%baza]));
	fclose(stdout);
	return 0;
}