Cod sursa(job #520699)

Utilizator NemultumituMatei Ionita Nemultumitu Data 10 ianuarie 2011 01:19:36
Problema Barbar Scor 70
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.97 kb
#include <cstdio>
#define inf 100000

int a[1001][1001];
bool viz[1001][1001];
int r, c, xi, yi, xo, yo, q, rez;
int coada[2][100000];
int dx[]={1,0,-1,0};
int dy[]={0,1,0,-1};

void citire()
{
	freopen ("barbar.in","r",stdin);
	freopen ("barbar.out","w",stdout);
	scanf("%d %d ", &r, &c);
	char ch;
	for (int i=1;i<=r;++i)
	{
		for (int j=1;j<=c;++j)
		{
			scanf("%c",&ch);
			if (ch=='.')
				a[i][j]=inf;
			if (ch=='*')
				a[i][j]=-1;
			if (ch=='D')
			{
				coada[0][q]=i;
				coada[1][q++]=j;
			}
			if (ch=='I')
			{
				xi=i;
				yi=j;
				a[i][j]=3000;
			}
			if (ch=='O')
			{
				xo=i;
				yo=j;
				a[i][j]=3000;
			}
		}
		scanf("\n");
	}
}

void bfinit()
{
	int p=0;
	while (p<q)
	{
		int x=coada[0][p], y=coada[1][p];
		for (int k=0;k<4;++k)
			if (a[x+dx[k]][y+dy[k]]>a[x][y]+1)
			{
				a[x+dx[k]][y+dy[k]]=a[x][y]+1;
				coada[0][q]=x+dx[k];
				coada[1][q++]=y+dy[k];
			}
		++p;
	}
}

void scrie()
{
	for (int i=1;i<=r;++i)
	{
		for (int j=1;j<=c;++j)
			printf("%d\t",a[i][j]);
		printf("\n");
	}
}

void reset()
{
	int i=0;
	while (coada[0][i])
	{
		coada[0][i]=0;
		coada[1][i++]=0;
	}
	for (i=1;i<=r;++i)
		for (int j=1;j<=c;++j)
			if (a[i][j]==-1)
				viz[i][j]=1;
			else
				viz[i][j]=0;
}

bool bfs(int m)
{
	reset();
	viz[xi][yi]=1;
	coada[0][0]=xi;
	coada[1][0]=yi;
	int p=0, q=1;
	bool sw=0;
	while (p<q)
	{
		int x=coada[0][p], y=coada[1][p];
		for (int k=0;k<4;++k)
			if (!viz[x+dx[k]][y+dy[k]]&&a[x+dx[k]][y+dy[k]]>=m)
			{
				viz[x+dx[k]][y+dy[k]]=1;
				coada[0][q]=x+dx[k];
				coada[1][q++]=y+dy[k];
				if (x+dx[k]==xo&&y+dy[k]==yo)
					sw=1;
			}
		++p;
	}
	return sw;
}

void bin(int inc, int sf)
{
	if (inc>sf)
		return;
	int m=(inc+sf)/2;
	if (!bfs(m))
		bin(inc,m-1);
	else
	{
		rez=m;
		bin(m+1,sf);
	}
}

int main()
{
	citire();
	bfinit();
	bin(1,r*c);
	if (rez)
		printf("%d",rez);
	else
		printf("-1");
	return 0;
}