Cod sursa(job #764633)

Utilizator cosminx2003Cosmin Clapon cosminx2003 Data 5 iulie 2012 19:14:44
Problema Barbar Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.03 kb
#include <iostream>
#include <fstream>
#include <queue>
#define N 1000
#define x first
#define y second

using namespace std;

ifstream f("barbar.in");
ofstream g("barbar.out");

int G[N][N],m,n;
queue<pair<int,int> > q;
pair<int,int> start,finish,node;
int visited[N][N];

int pathFind(int k) {
	bool found = false;
	int min = m*n,d;

	while(!q.empty()) q.pop();

	q.push(start);
	d = ++visited[start.x][start.y];
	while(!q.empty()) {
		node = q.front();
		q.pop();
		if(0 <= node.x-1 && G[node.x-1][node.y] >= k && visited[node.x-1][node.y] != d) {
			min = (min > G[node.x-1][node.y]) ? G[node.x-1][node.y] : min;
			visited[node.x-1][node.y] = d;
			q.push(make_pair(node.x-1,node.y));
		} else
			if(G[node.x-1][node.y] == -3) {
				found = true;
				break;
			}
		if(m > node.x+1 && G[node.x+1][node.y] >= k && visited[node.x+1][node.y] != d) {
			min = (min > G[node.x+1][node.y]) ? G[node.x+1][node.y] : min;
			visited[node.x+1][node.y] = d;
			q.push(make_pair(node.x+1,node.y));
		} else
			if(G[node.x+1][node.y] == -3) {
				found = true;
				break;
			}
		if(0 <= node.y-1 && G[node.x][node.y-1] >= k && visited[node.x][node.y-1] != d) {
			min = (min > G[node.x][node.y-1]) ? G[node.x][node.y-1] : min;
			visited[node.x][node.y-1] = d;
			q.push(make_pair(node.x,node.y-1));
		} else
			if(G[node.x][node.y-1] == -3) {
				found = true;
				break;
			}
		if(n > node.y+1 && G[node.x][node.y+1] >= k && visited[node.x][node.y+1] != d) {
			min = (min > G[node.x][node.y+1]) ? G[node.x][node.y+1] : min;
			visited[node.x][node.y+1] = d;
			q.push(make_pair(node.x,node.y+1));
		} else
			if(G[node.x][node.y+1] == -3) {
				found = true;
				break;
			}
	}

	return (found) ? min : 0;
}

int main() {
	char ch;
	int i,j,a,b,mid,path;

	f>>m>>n;
	for(i = 0; i < m; i++)
		for(j = 0; j < n; j++) {
			f>>ch;
			if(ch == '.')
				G[i][j] = -1;
			if(ch == 'I') {
				G[i][j] = -2;
				start = make_pair(i,j);
			}
			if(ch == 'D') {
				G[i][j] = 0;
				q.push(make_pair(i,j));
			}
			if(ch == 'O') {
				G[i][j] = -3;
				finish = make_pair(i,j);
			}
			if(ch == '*')
				G[i][j] = -4;
		}

	while(!q.empty()) {
		node = q.front();
		q.pop();
		if(0 <= node.x-1 && (G[node.x-1][node.y] == -1 ||
								 G[node.x-1][node.y]+1 < G[node.x-1][node.y])) {
			G[node.x-1][node.y] = G[node.x][node.y] + 1;
			q.push(make_pair(node.x-1,node.y));
		}
		if(m > node.x+1 && (G[node.x+1][node.y] == -1 ||
								 G[node.x+1][node.y]+1 < G[node.x+1][node.y])) {
			G[node.x+1][node.y] = G[node.x][node.y] + 1;
			q.push(make_pair(node.x+1,node.y));
		}
		if(0 <= node.y-1 && (G[node.x][node.y-1] == -1 ||
								 G[node.x][node.y-1]+1 < G[node.x][node.y-1])) {
			G[node.x][node.y-1] = G[node.x][node.y] + 1;
			q.push(make_pair(node.x,node.y-1));
		}
		if(n > node.y+1 && (G[node.x][node.y+1] == -1 ||
								 G[node.x][node.y+1]+1 < G[node.x][node.y+1])) {
			G[node.x][node.y+1] = G[node.x][node.y] + 1;
			q.push(make_pair(node.x,node.y+1));
		}
	}

	a = 0, b = m*n;
	while(b > a+1) {
		mid = (a+b)>>1;
		path = pathFind(mid);
		if(path)
			a = mid;
		else
			b = mid;
	}

	g<<path;

	return 0;
}