Cod sursa(job #550182)

Utilizator raduzerRadu Zernoveanu raduzer Data 9 martie 2011 12:01:11
Problema Barbar Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.95 kb
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

#define mp make_pair
#define x first
#define y second

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

const int MAX_N = 1001;
const int INF = 0x3f3f3f3f;

int n, m, k;
char s[MAX_N][MAX_N];
int d[MAX_N][MAX_N], f[MAX_N][MAX_N];
pair <int, int> q[MAX_N * MAX_N * 2], O;

void getDistance()
{
	int i, j;

	for (i = 1; i <= k; ++i)
	{
		for (j = 0; j < 4; ++j)
		{
			int newx = q[i].x + dx[j];
			int newy = q[i].y + dy[j];

			if (0 <= newx && newx < n && 0 <= newy && newy < m && s[newx][newy] != '*' && d[q[i].x][q[i].y] + 1 < d[newx][newy])
			{
				d[newx][newy] = d[q[i].x][q[i].y] + 1;
				q[++k] = mp(newx, newy);
			}
		}
	}
}

int check(int X)
{
	int i, j;
	k = 0;

	memset(f, 0, sizeof(f));

	for (i = 0; i < n && !k; ++i)
		for (j = 0; j < m; ++j)
			if (s[i][j] == 'I')
			{
				q[++k] = mp(i, j);

				if (d[i][j] < X)
					return 0;

				break;
			}

	f[q[1].x][q[1].y] = 1;

	for (i = 1; i <= k; ++i)
	{
		for (j = 0; j < 4; ++j)
		{
			int newx = q[i].x + dx[j];
			int newy = q[i].y + dy[j];

			if (0 <= newx && newx < n && 0 <= newy && newy < m && s[newx][newy] != '*' && d[newx][newy] >= X && !f[newx][newy])
			{
				q[++k] = mp(newx, newy);
				f[newx][newy] = 1;

				if (newx == O.x && newy == O.y)
					return 1;
			}
		}
	}

	return 0;
}

void binSearch()
{
	int l = 0, r = n + m, mij, ret = 0, ok = 0;

	while (l < r)
	{
		mij = (l + r) >> 1;

		if (check(mij))
			ret = mij, l = mij + 1, ok = 1;
		else
			r = mij - 1;
	}

	if (ok)
		printf("%d\n", ret);
	else
		printf("-1\n");
}

int main()
{
	int i, j;
	freopen("barbar.in", "r", stdin);
	freopen("barbar.out", "w", stdout);

	scanf("%d %d", &n, &m);

	memset(d, INF, sizeof(d));

	for (i = 0; i < n; ++i)
	{
		scanf("%s", s[i]);

		for (j = 0; j < m; ++j)
		{
			if (s[i][j] == 'D')
			{
				q[++k] = mp(i, j);
				d[i][j] = 0;
			}

			if (s[i][j] == 'O')
				O = mp(i, j);
		}
	}

	getDistance();

	binSearch();
}