Cod sursa(job #1830334)

Utilizator andreiulianAndrei andreiulian Data 16 decembrie 2016 15:49:46
Problema Barbar Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.3 kb
#include<iostream>
#include<fstream>
#include<queue>
#define mp make_pair
using namespace std;
int r, c, d[1005][1005];
int li, ci, lf, cf;
bool viz[1005][1005];
char m[1005][1005];
queue< pair<int, int> > q;
void dfsDragoni();
bool dfs(int dist);
int main() {
	ifstream in("barbar.in");
	ofstream out("barbar.out");
	int i, j;
	in >> r >> c;
	for (i = 1; i <= r; ++i) {
		for (j = 1; j <= c; ++j) {
			d[i][j] = 2000;
		}
	}
	for (i = 1; i <= r; ++i) {
		for (j = 1; j <= c; ++j) {
			in >> m[i][j];
			if(m[i][j] == 'D') {
				q.push( mp(i, j) );
				d[i][j] = 0;
			}
			if(m[i][j] == 'I') {
				li = i; ci = j;
			}
			if(m[i][j] == 'O') {
				lf = i; cf = j;
			}
		}
	}
	dfsDragoni();
	int sol, step, ok = 0;
	for(sol = 0, step = (1 << 11); step > 0 && sol + step <= 2100; step >>= 1) {
		for (i = 1; i <= r; ++i) {
			for (j = 1; j <= c; ++j) {
				viz[i][j] = 0;
			}
		}
		if (dfs(sol + step)) {
			sol += step;
			ok = 1;
		}
	}
	if (!ok) out << "-1\n";
	out << sol << '\n';
}

bool dfs(int dist) {
	if (d[li][ci] < dist) return 0;
	q.push( mp(li, ci) );
	viz[li][ci] = 1;
	int i, j;
	while (!q.empty()) {
		i = q.front().first;
		j = q.front().second;
		if (m[i][j] == 'O') {
			while(!q.empty()) {
				q.pop();
			}
			return 1;
		}
		q.pop();
		if (i - 1 && d[i - 1][j] >= dist && !viz[i - 1][j] && m[i - 1][j] != '*'){ 
			viz[i - 1][j] = 1;
			q.push( mp(i - 1, j) );
		}
		if (j + 1 <= c && d[i][j + 1] >= dist && !viz[i][j + 1] && m[i][j + 1] != '*') {
			viz[i][j + 1] = 1;
			q.push( mp(i, j + 1) );
		}
		if (i + 1 <= r && d[i + 1][j] >= dist && !viz[i + 1][j] && m[i + 1][j] != '*') {
			viz[i + 1][j] = 1;
			q.push( mp(i + 1, j) );
		}
		if (j - 1 && d[i][j - 1] >= dist && !viz[i][j - 1] && m[i][j - 1] != '*') {
			viz[i][j - 1] = 1;
			q.push( mp(i, j - 1) );
		}
	}
	return 0;
}

void dfsDragoni() {
	int i, j;
	while (!q.empty()) {
		i = q.front().first;
		j = q.front().second;
		q.pop();
		if (i - 1 && d[i - 1][j] > d[i][j] + 1){ 
			d[i - 1][j] = d[i][j] + 1;
			q.push( mp(i - 1, j) );
		}
		if (j + 1 <= c  && d[i][j + 1] > d[i][j] + 1) {
			d[i][j + 1] = d[i][j] + 1;
			q.push( mp(i, j + 1) );
		}
		if (i + 1 <= r && d[i + 1][j] > d[i][j] + 1) {
			d[i + 1][j] = d[i][j] + 1;
			q.push( mp(i + 1, j) );
		}
		if (j - 1 && d[i][j - 1] > d[i][j] + 1) {
			d[i][j - 1] = d[i][j] + 1;
			q.push( mp(i, j - 1) );
		}
	}
}