Cod sursa(job #564064)

Utilizator avram_florinavram florin constantin avram_florin Data 26 martie 2011 17:33:42
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.42 kb
#include<cstdio>
#include<queue>
#include<vector>

#define pb push_back
#define mkp make_pair
#define minim(a,b) ((a)<(b)?(a):(b))

using namespace std;

const int MaxN = 1001;
const int INF =0x3f3f3f3f;
const int dx[] = {0,0,1,0,-1};
const int dy[] = {0,1,0,-1,0};
const char in[] = "barbar.in";
const char out[] = "barbar.out";

int n,m,si,sj,fi,fj,ok;
int A[MaxN][MaxN],D[MaxN][MaxN],sol[MaxN][MaxN];
vector< pair<int,int> > Dr;
queue<int> Qi,Qj;

inline void read()
{
	freopen( in , "r" , stdin );
	scanf("%d %d\n" , &n , &m );
	char ch;
	int i,j;
	for( i = 1 ; i <= n ; i++ )
		{
			for( j = 1 ; j <= m ; j++ )
				{
					scanf("%c" , &ch );
					if( ch == '*' )A[i][j] = 1;
					if( ch == 'I' )si = i,sj = j;
					if( ch == 'O' )fi = i,fj = j;
					if( ch == 'D' )Dr.pb(mkp(i,j));
				}
			scanf("%c" , &ch);
		}
}

bool in_matrice(int x,int y)
{
	if( x > 0 && x <= n && y > 0 &&  y <= m )
		return true;
	return false;
}

void dragons()
{
	int i,j,k;
	for( i = 1 ; i <= n ; i++ )
		for( j = 1 ; j <= m ; j++ )
			D[i][j] = INF;
	vector< pair<int,int> >::iterator it = Dr.begin() , iend = Dr.end();
	for( ; it != iend ; ++it )
		{
			D[it->first][it->second] = 0;
			Qi.push(it->first);
			Qj.push(it->second);
		}
	for( ; !Qi.empty() ; Qi.pop() , Qj.pop() )
		{
			i = Qi.front();
			j = Qj.front();
			for( k = 1 ; k < 5 ; k++ )
				if( in_matrice(i+dx[k] , j + dy[k] ) )
					if( A[i+dx[k]][j+dy[k]] == 0 && D[i][j]+1 < D[i+dx[k]][j+dy[k]] )
						{
							D[i+dx[k]][j+dy[k]] = 1+D[i][j];
							Qi.push(i+dx[k]);
							Qj.push(j+dy[k]);
						}
		}
}

void solve()
{
	int i,j,k;
	ok = 0;
	for( i = 1 ; i <= n ; i++ )
		for( j = 1 ; j <= m ; j++ )
			sol[i][j] = -1;
	sol[si][sj] = D[si][sj] ;
	Qi.push(si);
	Qj.push(sj);
	for( ; !Qi.empty() ; Qi.pop() , Qj.pop() )
		{
			i = Qi.front();
			j = Qj.front();
			if( i == fi && j == fj )
				ok = 1;
			for( k = 1 ; k < 5 ; k++ )
				if( in_matrice(i+dx[k] , j+dy[k] ) )
					if( A[i+dx[k]][j+dy[k]] == 0 && minim(sol[i][j] , D[i+dx[k]][j+dy[k]]) > sol[i+dx[k]][j+dy[k]] )
						{
							sol[i+dx[k]][j+dy[k]] = minim(sol[i][j] , D[i+dx[k]][j+dy[k]] );
							Qi.push(i+dx[k]);
							Qj.push(j+dy[k]);
						}
		}
}

void write()
{
	freopen(out , "w" , stdout );
	if( !ok )
		printf("-1\n");
		else
		printf("%d\n" , sol[fi][fj]);
}

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