Cod sursa(job #31959)

Utilizator alextheroTandrau Alexandru alexthero Data 17 martie 2007 09:08:50
Problema Barbar Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.93 kb
#include <stdio.h>
#include <algorithm>
#include <vector>

#define inf 2000000000 
#define mp(i,j) make_pair(i,j)
#define fx first
#define fy second
#define nmax 1024

using namespace std;

int vx[] = {1,-1,0,0};
int vy[] = {0,0,1,-1};

char a[nmax][nmax],v[nmax][nmax];
int d[nmax][nmax],r,c,i,j,sx,sy;
pair <int,int> st[nmax * nmax];

inline int bun(int x,int y) {
	if(x < 1 || x > r) return 0;
	if(y < 1 || y > c) return 0;
	return 1;
}

void bfs_init() {
	// un bfs in urma caruia voi completa matricea d
	// d[x][y] - distanta pana la cel mai apropiat dragon
	int p = 0,cx,cy,nx,ny;
	for(int i = 1; i <= r; i++)
		for(int j = 1; j <= c; j++) {
			v[i][j] = 0;
			d[i][j] = inf - 1;
			if(a[i][j] == 'D') {
				v[i][j] = 1;
				st[++p] = mp(i,j);
				d[i][j] = 0;
			}
		}
	int q = 1;
	while(q <= p) {
		cx = st[q].fx;
		cy = st[q].fy;
		for(int i = 0; i < 4; i++) {
			nx = cx + vx[i];
			ny = cy + vy[i];
			if(bun(nx,ny) && !v[nx][ny]) {
				st[++p] = mp(nx,ny);
				d[nx][ny] = d[cx][cy] + 1;
				v[nx][ny] = 1;
			}
		}
		q++;
	}
}

int ok(int x) {
	memset(v,0,sizeof(v));
	int p = 1,nx,ny,cx,cy;
	st[1] = mp(sx,sy);
	v[sx][sy] = 1;
	int q = 1;
	while(q <= p) {
		cx = st[q].fx;
		cy = st[q].fy;
		for(int i = 0; i < 4; i++) {
			nx = cx + vx[i];
			ny = cy + vy[i];
			if(bun(nx,ny) && !v[nx][ny] && d[nx][ny] >= x) {
				st[++p] = mp(nx,ny);
				v[nx][ny] = 1;
				if(a[nx][ny] == 'O') return 1;
			}
		}
		q++;
	}

	return 0;
}

int cauta(int ls,int ld) {
	int r = inf;
	while(ls <= ld) {
		int m = (ls + ld) / 2;
		if(ok(m)) {
			r = m;
			ls = m + 1;
		}
		else ld = m - 1;
	}
	return r;
}

int main() {
	freopen("barbar.in","r",stdin);
	// freopen("barbar.out","w",stdout);
	
	scanf("%d%d\n",&r,&c);
	for(i = 1; i <= r; i++) {
		for(j = 1; j <= c; j++) {
			scanf("%c",&a[i][j]);
			if(a[i][j] == 'I') {
				sx = i;
				sy = j;
			}
		}
		scanf("\n");
	}

	bfs_init();

	int x = cauta(0,r * c);

	if(x == inf) printf("-1\n");
	else printf("%d\n",x);

	return 0;
}