Cod sursa(job #575459)

Utilizator joli94Apostol Adrian Alexandru joli94 Data 8 aprilie 2011 12:39:24
Problema Barbar Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.33 kb
#include<cstdio>
#include<cstring>
#include<queue>

using namespace std;

const int N=1005;
const int dlin[] = { 0 , 1 , 0 , -1 };
const int dcol[] = { 1 , 0 , -1 , 0 };

queue<pair<int , int> > q;
pair<int , int> xd , x , y;
char  a[N][N];
int dr[N][N] , dru[N][N] , x0 , y0 , xf , yf , c , r  , maxim = -1 ;


void read()
{
	freopen ( "barbar.in" , "r" , stdin );
	freopen ( "barbar.out" , "w" , stdout );
	
	scanf("%d %d\n" , &r, &c );
	for (int i=1 ; i<=r ; ++i)
	{
		gets(1+a[i]);
		for (int j=1 ; j<=c ; ++j)
		{
			if (a[i][j]=='I') 
			{
				x0 = i;
				y0 = j;
			}
			if (a[i][j]=='O')
			{
				xf = i;
				yf = j;
			}
			if (a[i][j]=='D') 
			{
				xd = make_pair(i,j);
				q.push(xd);
			}
			if (a[i][j]=='*') dr[i][j] = -1;
		}
	}
}

void bordare()
{
	for (int i=0 ; i<=r+1 ; ++i)
		dr[i][0] = dr[i][c+1] = -1;
	for (int j=0 ; j<=c+1 ; ++j)
		dr[0][j] = dr[r+1][j] = -1;
}

void bfs()
{
	while (!q.empty())
	{
		x = q.front();
		q.pop();
		for (int i=0 ; i<4 ; ++i)
		{
			y.first = x.first + dlin[i];
			y.second = x.second + dcol[i];
			if(a[y.first][y.second]!='*' && a[y.first][y.second]!='D' && dr[y.first][y.second]==0)
			{
				dr[y.first][y.second] =  1 + dr[x.first][x.second];
				q.push(y);
			}
		}
	}
}

void set()
{
	for (int i=0 ; i<= r+1 ; ++i)
	{
		for(int j=0 ; j<=c+1 ; ++j) 
			printf("%3d",dr[i][j]);
		printf("\n");
	}
}

void golire()
{
	while(!q.empty())
	{
		q.pop();
	}
	for(int i=1 ; i<=r ; ++i)
		for (int j=1 ; j<=c ; ++j)
			dru[i][j] = 0;

	bordare();
}

bool drum(int lim)
{
	golire();
	xd = make_pair(x0 , y0);
	q.push(xd);
	dru[x0][y0] = 1;
	while(!q.empty())
	{
		x = q.front();
		q.pop();
		for (int i=0 ; i<4 ; ++i)
		{
			y.first = x.first + dlin[i];
			y.second = x.second + dcol[i];
			if (dru[y.first][y.second] == 0 && a[y.first][y.second]!='*' && dr[y.first][y.second]>=lim)
			{
				dru[y.first][y.second] = 1 + dru[x.first][x.second];
				q.push(y);
			}
		}
	}
	if (dru[xf][yf]!=0) return true;
	return false;
}

int cautbin()
{
	int pas=1<<11,i;
	for (i=0 ; pas!=0 ; pas>>=1)
	{
		if (drum(i+pas))
			i += pas;
	}
	if(i==2048) return -1;
	return i;
}

void solve()
{
	bordare();
	bfs();
	//set();
	printf ( "%d\n" , cautbin());
}

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