Cod sursa(job #1234180)

Utilizator vladrochianVlad Rochian vladrochian Data 26 septembrie 2014 21:16:04
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.33 kb
#include <fstream>
#include <cstring>
#include <queue>
using namespace std;
const int NMAX = 1005, dx[] = {0, 1, 0 , -1}, dy[] = {-1, 0, 1, 0};

struct Coord {
	int x, y;
	Coord() {
		x = y = 0;
	}
	Coord(int nx, int ny) {
		x = nx;
		y = ny;
	}
	Coord(const Coord &other) {
		x = other.x;
		y = other.y;
	}
	Coord(const Coord &other, int dir) {
		x = other.x + dx[dir];
		y = other.y + dy[dir];
	}
} road_start, road_end;

int N, M, table[NMAX][NMAX], sol;
char current_line[NMAX];
bool viz[NMAX][NMAX];
queue<Coord> dragons;

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

void SetBorders() {
	for (int i = 1; i <= N; ++i)
		table[i][0] = table[i][M + 1] = -1;
	for (int i = 1; i <= M; ++i)
		table[0][i] = table[N + 1][i] = -1;
}

void GetDragonRange() {
	while (!dragons.empty()) {
		Coord crt(dragons.front());
		dragons.pop();
		for (int dir = 0; dir < 4; ++dir) {
			Coord nb(crt, dir);
			if (table[nb.x][nb.y] < -1) {
				table[nb.x][nb.y] = table[crt.x][crt.y] + 1;
				dragons.push(nb);
			}
		}
	}
}

bool IsRoad(int mx) {
	if (table[road_start.x][road_start.y] < mx || table[road_end.x][road_end.y] < mx)
		return false;
	memset(viz, 0, sizeof viz);
	queue<Coord> road;
	road.push(road_start);
	viz[road_start.x][road_start.y] = true;
	while (!road.empty()) {
		Coord crt(road.front());
		road.pop();
		for (int dir = 0; dir < 4; ++dir) {
			Coord nb(crt, dir);
			if (nb.x == road_end.x && nb.y == road_end.y)
				return true;
			else if (!viz[nb.x][nb.y] && table[nb.x][nb.y] >= mx) {
				viz[nb.x][nb.y] = true;
				road.push(nb);
			}
		}
	}
	return false;
}

void BinarySearch() {
	for (int bit = 1 << 10; bit; bit >>= 1)
		if (IsRoad(sol | bit))
			sol |= bit;
	if (!sol)
		if (!IsRoad(0))
			sol = -1;
}

int main() {
	fin >> N >> M;
	fin.ignore(1);
	memset(table, 0xf0, sizeof table);
	for (int i = 1; i <= N; ++i) {
		fin.getline(current_line + 1, NMAX);
		for (int j = 1; j <= M; ++j)
			switch(current_line[j]) {
				case 'I':
				road_start = Coord(i, j);
				break;
				case 'O':
				road_end = Coord(i, j);
				break;
				case 'D':
				table[i][j] = 0;
				dragons.push(Coord(i, j));
				break;
				case '*':
				table[i][j] = -1;
				break;
			}
	}
	SetBorders();
	GetDragonRange();
	BinarySearch();
	fout << sol << "\n";
	return 0;
}