Cod sursa(job #482657)

Utilizator Bogdan_tmmTirca Bogdan Bogdan_tmm Data 4 septembrie 2010 13:22:59
Problema Barbar Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.06 kb
#include<algorithm>
#include<queue>
#include<bitset>
using namespace std;
#define N_MAX 1001

int dist[N_MAX][N_MAX];
char a[N_MAX][N_MAX];
bitset <N_MAX> ut[N_MAX];
int n,m;

typedef pair <int,int> p;
queue <p> Q;
p Start;

int X[]={0,0,-1,1};
int Y[]={-1,1,0,0};

inline bool check(const int &i,const int &j)
{
	if(a[i][j]=='*')
		return 0;
	return 1<=i&&i<=n&&1<=j&&j<=m;
}

void SetDist()
{
	int i,j,x,y;
	p xy;
	for(i=1;i<=n;i++)
		for(j=1;j<=m;j++)
		{
			dist[i][j]=(1<<20);
			if(a[i][j]=='D')
			{
				Q.push(p(i,j));
				dist[i][j]=0;
				ut[i][j]=1;
			}
			if(a[i][j]=='I')
				Start=p(i,j);
		}

	while(!Q.empty())
	{
		xy=Q.front();	Q.pop();	ut[xy.first][xy.second]=0;
		
		for(i=0;i<4;i++)
		{
			x=xy.first+X[i];
			y=xy.second+Y[i];
			
			if(!check(x,y))
				continue;
			if(dist[x][y]<=dist[xy.first][xy.second]+1)
				continue;
			dist[x][y]=dist[xy.first][xy.second]+1;
			if(ut[x][y])
				continue;
			ut[x][y]=1;
			Q.push(p(x,y));
		}
	}
}

bool Finish(int D)
{
	int i,x,y;
	p xy;
	if(dist[Start.first][Start.second]<D)
		return 0;

	for(i=1;i<=n;i++)
		ut[i].reset();

	while(!Q.empty())
		Q.pop();

	Q.push(Start);	ut[Start.first][Start.second]=1;
	while(!Q.empty())
	{
		xy=Q.front();	Q.pop();
		
		for(i=0;i<4;i++)
		{
			x=xy.first+X[i];
			y=xy.second+Y[i];
			if(a[x][y]=='O')
				return 1;
			if(!check(x,y))
				continue;
			if(dist[x][y]<D)
				continue;
			if(ut[x][y])
				continue;
			ut[x][y]=1;
			Q.push(p(x,y));
		}
	}
	return 0;
}

int Solve()
{
	int Dr=0,i,j,step;
	for(i=1;i<=n;i++)
		for(j=1;j<=m;j++)
			if(a[i][j]!='*')
				Dr=max(Dr,dist[i][j]);
	
	for(step=1;step<=Dr;(step<<=1));

	for(i=-1;step;(step>>=1))
		if(i+step<=Dr&&Finish(i+step))
			i+=step;
	return i;
}

int main()
{
	freopen("barbar.in","r",stdin);
	freopen("barbar.out","w",stdout);
	
	scanf("%d%d\n",&n,&m);

	int i,j;
	for(i=1;i<=n;i++)
	{
		for(j=1;j<=m;j++)
			scanf("%c",&a[i][j]);
		scanf("\n");
	}
	
	SetDist();

	printf("%d\n",Solve());

	return 0;
}