Cod sursa(job #631640)

Utilizator toniobFMI - Barbalau Antonio toniob Data 9 noiembrie 2011 11:26:40
Problema Barbar Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.29 kb
#include <fstream>
#include <cstdio>

using namespace std;
ifstream in ("barbar.in");
FILE* out = fopen ("barbar.out", "w");

const int dlin[] = {-1, 0, 1, 0};
const int dcol[] = {0, 1, 0, -1};
struct punct {
	int x, y;
};
const int INF = 1000000;
punct coada_dist[1 << 20], inceput, sfarsit;
int r, c, dist[1 << 10][1 << 10], coada_dist_u, coada_dist_p;
char s[1 << 10];
bool mat[1<<10][1<<10];
punct coada[(1000 + 2) * (1000 + 2)];

void lee_dist () {
	punct x1, y1;
	
	while (coada_dist_u != coada_dist_p) {
		x1 = coada_dist[++coada_dist_p];
		
		for (int i = 0; i < 4; ++i) {
			y1.x = x1.x + dlin[i];
			y1.y = x1.y + dcol[i];
			
			if (dist[y1.x][y1.y] == INF) {
				dist[y1.x][y1.y] = 1 + dist[x1.x][x1.y];
				
				coada_dist[++coada_dist_u] = y1;
			}
		}
	}
}

bool ajuns (int distanta) {
	
	for (int i = 1; i <= r; ++i) {
		for (int j = 1; j <= c; ++j) {
			mat[i][j] = false;
		}
	}
	
	punct x1, y1;
	int p = 0, u = 0;
	
	coada[u++] = inceput;
	mat[inceput.x][inceput.y] = true;
	while (p != u) {
		x1 = coada[p++];
		
		
		for (int i = 0; i < 4; ++i) {
			y1.x = x1.x + dlin[i];
			y1.y = x1.y + dcol[i];
			
			if (dist[y1.x][y1.y] >= distanta && dist[y1.x][y1.y] != -1 && !mat[y1.x][y1.y]) {
				coada[u++] = y1;
				mat[y1.x][y1.y] = true;
			}
		}
	}
	
	return mat[sfarsit.x][sfarsit.y];
}

int bs () {
	int i, step = 1 << 30;
	
	for (i = 0; step; step >>= 1) {
		if (ajuns(i + step)) {
			i += step;
		}
	}
	
	return i;
}

int main () {
	in >> r >> c >> ws;
	
	for (int i = 1; i <= r; ++i) {
		for (int j = 1; j <= c; ++j) {
			dist[i][j] = INF;
		}
	}
	
	for (int i = 1; i <= r; ++i) {
		in.getline (s + 1, c + 2);
		
		for (int j = 1; s[j]; ++j) {
			if (s[j] == 'D') {
				coada_dist[++coada_dist_u].x = i;
				coada_dist[coada_dist_u].y = j;
				
				dist[i][j] = 0;
				
				continue;
			}
			
			if (s[j] == 'I') {
				inceput.x = i, inceput.y = j;
				
				continue;
			}
			
			if (s[j] == 'O') {
				sfarsit.x = i, sfarsit.y = j;
				
				continue;
			}
			
			if (s[j] == '*') {
				dist[i][j] = -1;
			}
		}
	}
	
	for (int i = 0; i <= r + 1; ++i) {
		dist[i][0] = -1;
		dist[i][c + 1] = -1;
	}
	for (int i = 0; i <= c + 1; ++i) {
		dist[0][i] = -1;
		dist[r + 1][i] = - 1;
	}
	
	lee_dist ();
	
	int rez = bs ();
	
	if (!rez) {
		fprintf (out, "-1\n");
		
		return 0;
	}
	
	fprintf (out, "%d\n", rez);
	
	return 0;
}