Cod sursa(job #1415985)

Utilizator theprdvtheprdv theprdv Data 7 aprilie 2015 00:34:59
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.24 kb
#include <fstream>
#include <queue>

using namespace std;
fstream fout("barbar.out", ios::out);
fstream fin("barbar.in", ios::in);

struct coord{
	int row, col;
} node;

class compare{
public:
	bool operator()(pair<int, coord> a, pair<int, coord> b){
		return a.first < b.first;
	}
};

#define MAXN 1005
int R, C, map[MAXN][MAXN], dist = ~(1 << 31), found;
queue <coord> q;
vector <coord> start;
priority_queue <pair<int, coord>, vector<pair<int, coord>>, compare> heap;

void read()
{
	char x;
	fin >> R >> C;
	for (int i = 1; i <= R; i++)
		for (int j = 1; j <= C; j++){
			fin >> x;
			node.row = i, node.col = j;
			map[i][j] = x == '*' ? - 1 : x == 'D' ? 1 : 0;
			if (x == 'D')  q.push(node);
			if (x == 'O' || x == 'I')  start.push_back(node);
		}
	fin.close();
}
inline void neighbour(int curr, int next_i, int next_j, int dr = 1)
{
	if (next_i > R || next_i < 1 || next_j > C || next_j < 1)  return;
	if (map[next_i][next_j] && dr)  return;
	if (map[next_i][next_j] == -1) return;
	node.row = next_i, node.col = next_j;
	if (dr)
		map[next_i][next_j] = curr + 1,
		q.push(node);
	else
		heap.push(make_pair(map[next_i][next_j], node)),
		map[next_i][next_j] = -1;
}

int main()
{
	read();
	while (!q.empty()){
		int i = q.front().row, j = q.front().col;
		neighbour(map[i][j], i - 1, j);			// north check
		neighbour(map[i][j], i + 1, j);			// south check
		neighbour(map[i][j], i, j - 1);			// east check
		neighbour(map[i][j], i, j + 1);			// west check
		q.pop();
	}

	node = start.back(); start.pop_back();
	heap.push(make_pair(map[node.row][node.col], node));

	while (!heap.empty()){
		coord now = heap.top().second;
		int cost = heap.top().first;
		heap.pop();
		dist = min(dist, cost);
		if (now.row == start.back().row && now.col == start.back().col){
			found = true;
			break;
		}
		neighbour(cost, now.row - 1, now.col, 0);			// north check
		neighbour(cost, now.row + 1, now.col, 0);			// south check
		neighbour(cost, now.row, now.col - 1, 0);			// east check
		neighbour(cost, now.row, now.col + 1, 0);			// west check
		map[now.row][now.col] = -1;
	}
	if (!found) fout << -1;
	else if (dist == 0) fout << R * C;
	else fout << dist - 1;
	fout << "\n";

	fout.close();
	return 0;
}