Cod sursa(job #699020)

Utilizator CBogdanCiobanu Bogdan CBogdan Data 29 februarie 2012 17:12:28
Problema Barbar Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.87 kb
#include<cstdio>
#include<vector>
#include<queue>
#include<utility>
#include<algorithm>
using namespace std;

int n,m,i,j,x,y,X,Y,sol,OY[4]={-1,0,1,0},OX[4]={0,1,0,-1},dist[1002][1002],viz[1002][1002],lee(int);
pair<int,int> beg,end;
queue<pair<int,int> > Q;

void read(),solve();

int main()
{
	read();
	solve();
	
	return 0;
}

void read()
{
	freopen("barbar.in","r",stdin);
	freopen("barbar.out","w",stdout);
	scanf("%d%d\n",&n,&m);
	char aux;
	//gets(linie);
	for(i=1;i<=n;i++)
	{
		//gets(linie);
		for(j=0;j<m;j++)
		{
			scanf("%c",&aux);
			if(aux=='D'){Q.push(make_pair(i,j+1));viz[i][j+1]=1;dist[i][j+1]=1;}
			else if(aux=='I')beg=make_pair(i,j+1);
			else if(aux=='O')end=make_pair(i,j+1);
			else if(aux=='*'){dist[i][j+1]=-1;viz[i][j+1]=1;}
		}
		scanf("\n");
	}
	for(i=0;i<=n+1;i++)dist[i][0]=dist[i][m+1]=-1;
	for(i=0;i<=m+1;i++)dist[0][i]=dist[n+1][i]=-1;
}

void solve()
{
	for(;Q.size();Q.pop())
	{
		x=Q.front().first;y=Q.front().second;
		for(i=0;i<4;i++)
		{
			X=x+OY[i],Y=y+OX[i];
			if(!dist[X][Y])
			{
				viz[X][Y]=1;
				dist[X][Y]=dist[x][y]+1;
				Q.push(make_pair(X,Y));
			}
			if(dist[X][Y]>dist[x][y]+1)
				dist[X][Y]=dist[x][y]+1;
		}
	}
	int left,mid,right;
	left=0;
	right=min(dist[beg.first][beg.second],dist[end.first][end.second]);
	while(right-left>1)
	{
		mid=(left+right)/2;
		if(lee(mid))
		{
			left=mid;
			sol=mid;
		}
		else
			right=mid;
	}
	printf("%d\n",sol-1);
}
int lee(int minim)
{
	memset(viz,0,sizeof(viz));viz[beg.first][beg.second]=1;
	while(Q.size())Q.pop();
	Q.push(beg);
	for(;Q.size();Q.pop())
	{
		x=Q.front().first;y=Q.front().second;
		for(i=0;i<4;i++)
		{
			X=x+OY[i];Y=y+OX[i];
			if(dist[X][Y]>=minim && !viz[X][Y])
			{
				Q.push(make_pair(X,Y));
				viz[X][Y]=viz[x][y]+1;
			}
			if(X==end.first&&Y==end.second)return 1;
		}
	}
	return 0;
}