Cod sursa(job #414687)

Utilizator Teodor94Teodor Plop Teodor94 Data 10 martie 2010 13:09:26
Problema Barbar Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.5 kb
#include<cstdio>

const int N=1<<10;

const int dx[]={-1,0,1,0};//N,E,S,V
const int dy[]={0,1,0,-1};//N,E,S,V

char s[N][N];
int x1[N*N],y1[N*N],x[N*N],y[N*N],nn,a[N][N],n,m,nr,xs,ys,xxi,yyi;
bool fr[N][N];

bool dragon(int xx,int yy)
{
	if (s[xx][yy]=='D')
		return true;
	return false;
}

bool liber(int xx,int yy)
{
	if (s[xx][yy]=='.' || s[xx][yy]=='I' || s[xx][yy]=='O')
		return true;
	return false;
}

void lee(int xx,int yy)
{
	if (xx-1>=0 && liber(xx-1,yy) && (a[xx-1][yy]>a[xx][yy]+1 || a[xx-1][yy]==0))
	{
		nn++;
		x1[nn]=xx-1;
		y1[nn]=yy;
		a[xx-1][yy]=a[xx][yy]+1;
	}
	if (yy+1<m && liber(xx,yy+1) && (a[xx][yy+1]>a[xx][yy]+1 || a[xx][yy+1]==0))
	{
		nn++;
		x1[nn]=xx;
		y1[nn]=yy+1;
		a[xx][yy+1]=a[xx][yy]+1;
	}
	if (xx+1<n && liber(xx+1,yy) && (a[xx+1][yy]>a[xx][yy]+1 || a[xx+1][yy]==0))
	{
		nn++;
		x1[nn]=xx+1;
		y1[nn]=yy;
		a[xx+1][yy]=a[xx][yy]+1;
	}
	if (yy-1>=0 && liber(xx,yy-1) && (a[xx][yy-1]>a[xx][yy]+1 || a[xx][yy-1]==0))
	{
		nn++;
		x1[nn]=xx;
		y1[nn]=yy-1;
		a[xx][yy-1]=a[xx][yy]+1;
	}
}

void init()
{
	nr=0;
	for (int i=0;i<n;i++)
		for (int j=0;j<n;j++)
			if (s[i][j]=='O')
			{
				xs=i;
				ys=j;
			}
			else
			if (s[i][j]=='I')
			{
				xxi=i;
				yyi=j;
			}
}

bool ok(int d)
{
	for (int i=0;i<n;i++)
		for (int j=0;j<m;j++)
			fr[i][j]=false;
	int p,u,pcx,pcy,pux,puy;
	p=u=0;
	x[u]=xxi;
	y[u++]=yyi;
	if (a[xxi][yyi]<d)
		return false;
	// marchez ca am fost in xxi,yyi
	fr[xxi][yyi]=true;
	while (p<u)
	{
		pcx=x[p];
		pcy=y[p++];
		for(int i=0 ; i<4 ; ++i)
		{
			pux=pcx+dx[i];
			puy=pcy+dy[i];
			if (pux>=0 && pux<n && puy>=0 && puy<m && a[pux][puy]>=d && !fr[pux][puy])
			{
				x[u]=pux;
				y[u++]=puy;
				fr[pux][puy]=true;
				//adaug in coada (pux,puy)
				//marchez ca am fost in (pux,puy)
			}
		}
	}
	//daca poz finala e marcata, return true
	return fr[xs][ys];
}

int cautbin()
{
	int pas=1<<12,i;
	for (i=0;pas;pas>>=1)
		if (ok(i+pas))
			i+=pas;
	return i;
}

int main()
{
	freopen("barbar.in","r",stdin);
	freopen("barbar.out","w",stdout);
	scanf("%d%d\n",&n,&m);
	nr=0;
	for (int i=0;i<n;i++)
	{
		gets(s[i]);
		for (int j=0;s[i][j];j++)
			if (dragon(i,j))
			{
				nr++;
				x[nr]=i;
				y[nr]=j;
			}
	}
	while (nr)
	{
		nn=0;
		for (int i=1;i<=nr;i++)
			lee(x[i],y[i]);
		nr=nn;
		for (int i=1;i<=nr;i++)
		{
			x[i]=x1[i];
			y[i]=y1[i];
		}
	}
	init();
	int x=cautbin();
	if (x==0)
		x=-1;
	printf("%d\n",x);
	return 0;
}