Cod sursa(job #366357)

Utilizator cezar305Mr. Noname cezar305 Data 21 noiembrie 2009 16:58:58
Problema Barbar Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.38 kb
#include <cstdio>
#include <cstring>
#define maxn 512

using namespace std;

struct poz {
	int x, y;
};

const int dl[4] = {1, -1, 0, 0};
const int dc[4] = {0, 0, 1, -1};

int n, m, nr, i, j;
int v[maxn][maxn];
char s[maxn];
int dist[maxn][maxn], viz[maxn][maxn];
poz q[maxn * maxn], start, stop;

void bfs1() {
	int p, u, lnou, cnou, l, c, d;
	p = 1; u = nr;
	memset(viz, 0, sizeof(viz));
	for (i = 1; i <= nr; i++)
		viz[q[i].x][q[i].y] = 1;
	
	while (p <= u) {
		l = q[p].x; c = q[p].y;
		for (d = 0; d < 4; d++) {
			lnou = l + dl[d];
			cnou = c + dc[d];
			if (lnou > 0 && lnou <= n && cnou > 0 && cnou <= m) 
				if (viz[lnou][cnou] == 0 && v[lnou][cnou] != -1) {
					viz[lnou][cnou] = 1;
					dist[lnou][cnou] = dist[l][c] + 1;
					u++;
					q[u].x = lnou; q[u].y = cnou;
				}
		}
		p++;
	}
}

inline bool posibil(int t) {
	int p, u, d, l, c, lnou, cnou;
	memset(viz, 0, sizeof(viz));
	p = u = 1;
	q[1] = start;
	
	while (p <= u) {
		l = q[p].x; c = q[p].y;
		for (d = 0; d < 4; d++) {
			lnou = l + dl[d];
			cnou = c + dc[d];
			if (lnou > 0 && lnou <= n && cnou > 0 && cnou <= m) 
				if (viz[lnou][cnou] == 0 && dist[lnou][cnou] >= t && v[lnou][cnou] != -1) {
					viz[lnou][cnou] = 1;
					u++;
					if (lnou == stop.x && cnou == stop.y)
						return true;
					q[u].x = lnou; q[u].y = cnou;
				}
		}
		p++;
	}
	
	if (viz[stop.x][stop.y])
		return true;
	return false;
}

inline int bsearch(int left, int right) {
	int m, rez = 0;
	while (left <= right) {
		m = (left + right) / 2;
		if (posibil(m)) {
			if (m > rez)
				rez = m;
			left = m + 1;
		}
		else
			right = m - 1;
	}
	
	return rez;
}

int main() {
	freopen("barbar.in", "r", stdin);
	freopen("barbar.out", "w", stdout);
	scanf("%d%d ", &n, &m);
	for (i = 1; i <= n; i++) {
		fgets(s, 503, stdin);
		for (j = 0; j < m; j++) {
			if (s[j] == 'D') {
				nr++;
				q[nr].x = i; q[nr].y = j + 1;
				v[i][j + 1] = 1;
			}
			if (s[j] == 'I') {
				start.x = i; start.y = j + 1;
				v[i][j + 1] = 2;
			}
			if (s[j] == 'O') {
				stop.x = i; stop.y = j + 1;
				v[i][j + 1] = 3;
			}
			if (s[j] == '*') {
				v[i][j + 1] = -1;
			}
			
		}
	}
	
	bfs1();
	
/*	for (i = 1; i <= n; i++) {
		for (j = 1; j <= m; j++)
			printf("%d ", dist[i][j]);
		printf("\n");
	}*/
	
	printf("%d\n", bsearch(0, dist[start.x][start.y]));
	
	return 0;
}