Cod sursa(job #118609)

Utilizator vlad.maneaVlad Manea vlad.manea Data 27 decembrie 2007 00:36:49
Problema Barbar Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.12 kb
#include <stdio.h>
#define nmax 105
#define infinit 32767

int dist[nmax][nmax], care[nmax][nmax], X[nmax*nmax*nmax*nmax/2], Y[nmax*nmax*nmax*nmax/2];

int xi, yi, xf, yf, ic, sc, l, m, r, x, y, i, j, ok, ans;

int N, M;

char c;

int dx[] = { 0, 1, 0, -1};
int dy[] = { 1, 0, -1, 0};

void read();
void solve();
void write();
int test(int);

int main()
{
	read();

	solve();

	write();

	return 0;
}

int test(int m)
{
	if (dist[xi][yi] < m || dist[xf][yf] < m) return 0;

	for (ic=sc=0,X[ic]=xi,Y[ic]=yi; ic <= sc && care[xf][yf] != m;++ic)
	{
		x = X[ic];
		y = Y[ic];

		for (i = 0; i < 4; ++i)
			if (care[x + dx[i]][y + dy[i]] != m && dist[x+dx[i]][y+dy[i]] >= m
			&& x+dx[i] >= 1 && x+dx[i] <= N
			&& y+dy[i] >= 1 && y+dy[i] <= M)
			{
				++sc;
				X[sc] = x+dx[i];
				Y[sc] = y+dy[i];
				care[x+dx[i]][y+dy[i]] = m;
			}
	}

	if (care[xf][yf] == m) return 1;

	return 0;
}

void read()
{
	freopen("barbar.in", "r", stdin);
	scanf("%d%d", &N, &M);
	scanf("%c", &c);

	for (i = 1; i <= N; ++i)
	{
		for (j = 1; j <= M; ++j)
		{
			dist[i][j] = infinit;

			scanf("%c", &c);

			switch(c)
			{
				case '*':
				{
					dist[i][j] = 0;
					break;
				}
				case 'D':
				{
					dist[i][j] = 0;
					++sc;
					X[sc] = i;
					Y[sc] = j;
					break;
				}
				case 'I':
				{
					xi = i;
					yi = j;
					break;
				}
				case 'O':
				{
					xf = i;
					yf = j;
					break;
				}
				default:
				{
					break;
				}
			}
		}

		scanf("%c", &c);
	}
}

void solve()
{
	for (ic = 1; ic <= sc; ++ic)
		for (i = 0, x = X[ic], y = Y[ic]; i < 4; ++i)
			if (dist[x + dx[i]][y + dy[i]] > dist[x][y]+1
			&& x+dx[i] >= 1 && x+dx[i] <= N
			&& y+dy[i] >= 1 && y+dy[i] <= M)
			{
				dist[x + dx[i]][y + dy[i]] = dist[x][y] + 1;
				++sc;
				X[sc] = x + dx[i];
				Y[sc] = y + dy[i];
			}

	for (l = 1, r = N*M; l <= r; )
	{
		m = (l+r) >> 1;

		ok = test(m);

		if (ok)
		{
			if (m > ans) ans = m;

			l = m+1;
		}
		else
			r = m-1;
	}
}

void write()
{
	freopen("barbar.out", "w", stdout);

	printf("%d\n", ans);
}