Cod sursa(job #550197)

Utilizator tvladTataranu Vlad tvlad Data 9 martie 2011 12:06:17
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.71 kb
#include <fstream>
#include <iostream>
#include <string>
#include <queue>
using namespace std;

const int N_MAX = 1000;
const int M_MAX = 1000;
const int ND = 4;
const int DX[ND] = { 0, 1, 0, -1};
const int DY[ND] = { 1, 0, -1, 0};
const int INF = 0x3f3f3f3f;

ifstream fin("barbar.in");
ofstream fout("barbar.out");

int n, m;
pair<int, int> start, end;
string s[N_MAX];
int d[N_MAX][N_MAX];
bool used[N_MAX][N_MAX];

void getDragonDistance() {
	for (int i = 0; i < n; ++i)
		fill(d[i], d[i]+m, INF);
	queue < pair<int,int> > q;
	for (int i = 0; i < n; ++i) {
		for (int j = 0; j < m; ++j) {
			if (s[i][j] == 'D') {
				d[i][j] = 0;
				q.push(make_pair(i, j));
			}
		}
	}
	for (; !q.empty(); q.pop()) {
		pair<int,int> &curr = q.front();
		for (int i = 0; i < ND; ++i) {
			pair<int,int> next = make_pair ( curr.first + DX[i], curr.second + DY[i] );
			if (0 <= next.first && next.first < n &&
				0 <= next.second && next.second < m &&
				s[next.first][next.second] != '*' &&
				d[next.first][next.second] > d[curr.first][curr.second] + 1) {
				q.push(next);
				d[next.first][next.second] = d[curr.first][curr.second] + 1;
			}
		}
	}
}

bool checkPath ( int dist ) {
//	cerr << "Checking " << dist << '\n';
	for (int i = 0; i < n; ++i)
		fill(used[i], used[i]+m, false);
	queue < pair<int,int> > q;
	used[start.first][start.second] = true;
//	cerr << d[start.first][start.second] << '\n';
	if (d[start.first][start.second] < dist)
		return false;
//	cerr << start.first << ' ' << start.second << '\n';
	for (q.push(start); !q.empty(); q.pop()) {
		pair<int,int> &curr = q.front();
		for (int i = 0; i < ND; ++i) {
			pair<int,int> next = make_pair ( curr.first + DX[i], curr.second + DY[i] );
			if (0 <= next.first && next.first < n &&
				0 <= next.second && next.second < m &&
				(s[next.first][next.second] != '*' || s[next.first][next.second] != '*') &&
				d[next.first][next.second] >= dist &&
				!used[next.first][next.second]) {
//				cerr << next.first << ' ' << next.second << '\n';
				if (next.first == end.first && next.second == end.second) {
//					cerr << "Ok\n";
					return true;
				}
				q.push(next);
				used[next.first][next.second] = true;
			}
		}
	}
//	cerr << "Nope\n";
	return false;
}

int getPath () {
	int ret = -1;
	for (int step = 1 << 10; step; step >>= 1)
		if (checkPath(ret + step))
			ret += step;
	return ret;
}

int main() {
	fin >> n >> m;
	for (int i = 0; i < n; ++i) {
		fin >> s[i];
		for (int j = 0; j < m; ++j) {
			if (s[i][j] == 'I') start.first = i, start.second = j; else
			if (s[i][j] == 'O') end.first = i, end.second = j;
		}
	}

//	cerr << start.first << ' ' << start.second << " - " << end.first << ' ' << end.second << '\n';

	getDragonDistance();	

	int ans = getPath();
	fout << ans << '\n';
	return 0;
}