Cod sursa(job #146949)

Utilizator MarquiseMarquise Marquise Data 2 martie 2008 14:04:49
Problema Barbar Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.28 kb
#include <stdio.h>
#include <string.h>

#define NMAX 1001
#define QMAX 1000005
#define INF 1 << 30

int N, M, m[NMAX][NMAX], nq, max;
int ll[] = { -1, 1, 0, 0 }, cc[] = {0, 0, -1, 1};

char viz[NMAX][NMAX];

struct temnita
{
	int l, c;
};

temnita q[QMAX], b, e;


inline int MIN(int a, int b)
{
	return a < b ? a : b;
}


void init()
{
	int i, j;
	for ( i = 0; i <= M + 1; i++)
		m[0][i] = m[N + 1][i] = -1;
	for ( i = 1; i <= N; i++)
		m[i][0] = m[i][M + 1] = -1;
}


int bf(int x)
{
	int i, st, dr, ex = 0, cx, cy;

	for ( i = 1; i <= N; i++)
		memset(viz[i], '0', sizeof(viz[i]));
	st = dr = 1;
	viz[b.l][b.c] = '1';
	q[1] = b;
	while ( st <= dr && !ex )
	{
		for ( i = 0; i < 4; i++)
		{
			cx = q[st].l + ll[i];
			cy = q[st].c + cc[i];
			if ( m[cx][cy] >= x && viz[cx][cy] == '0' )
			{
				dr++;
				viz[cx][cy] = '1';
				q[dr].l = cx;
				q[dr].c = cy;
				if ( cx == e.l && cy == e.c)
					ex = 1;
			}
		}
		st++;
	}
	return ex;
}



int main()
{
	int i, j, st, dr, cx, cy, p, mij;
	char c;

	freopen("barbar.in", "r", stdin);
	freopen("barbar.out", "w", stdout);
	scanf("%d %d ", &N, &M);
	for ( i = 1; i <= N; i++)
	{
		for ( j = 1; j <= M; j++)
		{
			scanf("%c", &c);
			switch (c)
			{
				case 'D': { nq++; q[nq].l = i; q[nq].c = j; } break;
				case '*':   m[i][j] = -1; break;
				case 'I': { b.l = i;  b.c = j; m[i][j] = INF;} break;
				case 'O': { e.l = i;  e.c = j; m[i][j] = INF; } break;
				case '.':  m[i][j] = INF;
			}
		}
		scanf("%c", &c);
	}

	init();
	st = 1;
	dr = nq;
	while ( st <= dr)
	{

		for ( i = 0; i < 4; i++)
		{
			cx = q[st].l + ll[i];
			cy = q[st].c + cc[i];
			p = m[q[st].l][q[st].c] + 1;
			if ( m[cx][cy] != -1  && m[cx][cy] != 0 && p < m[cx][cy])
			{
				dr++;
				m[cx][cy] = p;
				q[dr].l = cx;
				q[dr].c = cy;

			}
		}
		st++;
	}
    if ( m[b.l][b.c] == INF || m[e.l][e.c] == INF)
       printf("-1\n");
    else
    {    
	     dr = MIN( m[b.l][b.c], m[e.l][e.c] );
	     st = 1;
	     while ( st <= dr )
	     {
		      mij = ( st + dr ) / 2;
		      if ( bf(mij) )
		      {
			      max = mij;
			      st = mij + 1;
		      }
		      else
			      dr  = mij - 1;
	     }

	printf("%d\n", max);
    }               
	return 0;

}