Cod sursa(job #852096)

Utilizator crushackPopescu Silviu crushack Data 10 ianuarie 2013 20:57:12
Problema Barbar Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.79 kb
#include <stdio.h>
#include <string.h>
#include <queue>
#define NMax 1010
using namespace std;

const char IN[]="barbar.in",OUT[]="barbar.out";
const int d[4][2]= { {-1,0} , {0,1} , {1,0} , {0,-1} };

int N,M,L;
int Dist[NMax][NMax];
char s[NMax][NMax];
bool b[NMax][NMax],b2[NMax][NMax],p[NMax][NMax];

struct pct{
	int x,y;
}S,F,D[NMax*NMax];

queue<pct> qu;

void drag()
{
	int i;
	for (i=1;i<=L;++i) qu.push(D[i]);

	while (!qu.empty())
	{
		pct x=qu.front();
		qu.pop();

		for (i=0;i<4;++i)
		{
			pct tmp={x.x+d[i][0],x.y+d[i][1]};
			if (tmp.x>0 && tmp.x<=N && tmp.y>0 && tmp.y<=M && !b2[tmp.x][tmp.y])
			{
				qu.push(tmp);
				b2[tmp.x][tmp.y]=true;
				Dist[tmp.x][tmp.y]=1+Dist[x.x][x.y];
			}
		}
	}
}

bool fill(int x,int y,int L)
{
	if (p[x][y] || b[x][y] || Dist[x][y]<L) return false;
	p[x][y]=true;
	if (x==F.x && y==F.y) return true;
	for (int i=0;i<4;++i)
		if (fill(x+d[i][0],y+d[i][1],L))
			return true;
	return false;
}

bool test(int L)
{
	memset(p,0,sizeof(p));
	return fill(S.x,S.y,L);
}

int search(int L)
{
	int i,step;
	for (step=1;step<L;step<<=1);
	for (i=0;step;step>>=1)
		if (i+step<=L && test(i+step))
			i+=step;
	return i==0 ? -1 : i;
}

int main()
{
	int i,j;
	freopen(IN,"r",stdin);
	scanf("%d%d",&N,&M);
	for (i=1;i<=N;++i)
		scanf("%s",s[i]+1);
	fclose(stdin);

	for (i=1;i<=N;++i) for (j=1;j<=M;++j)
	{
		if (s[i][j]=='I') S.x=i,S.y=j;
		if (s[i][j]=='O') F.x=i,F.y=j;
		if (s[i][j]=='*') b[i][j]=b2[i][j]=true;
		if (s[i][j]=='D') ++L,D[L].x=i,D[L].y=j;
	}

	for (i=1;i<=N;++i) b2[i][0]=b2[i][M+1]=b[i][0]=b[i][M+1]=true;
	for (i=1;i<=M;++i) b2[0][i]=b2[N+1][i]=b[0][i]=b[N+1][i]=true;

	drag();

	freopen(OUT,"w",stdout);
	printf("%d\n",search(max(N,M)));
	fclose(stdout);

	return 0;
}