Cod sursa(job #1492519)

Utilizator aimrdlAndrei mrdl aimrdl Data 27 septembrie 2015 20:47:51
Problema Barbar Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.19 kb
#include <stdio.h>
#include <queue>
#include <vector>
#include <algorithm>

#define IN -1
#define OUT -2
#define DRAGON 0
#define FREE -3
#define BLOCKED -4

using namespace std;

typedef struct {
	int i, j;
	int d;
} TPos;

int R, C, Ii, Ij, Oi, Oj, Max;
int M[1005][1005];
int dx[4] = {-1, 1, 0, 0};
int dy[4] = {0, 0, -1, 1};

queue < pair <int, int> > Q;

void read() {
	scanf("%d %d\n", &R, &C);
	
	char buffer[1005];
	
	for (int i = 0; i < R; ++i) {
		fgets(buffer, 1005, stdin);
		for (int j = 0; j < C; ++j) {
			switch (buffer[j]) {
				case '.': M[i][j] = FREE; break;
				case 'D': {
					M[i][j] = DRAGON; 
					Q.push(make_pair(i, j));
					break;
				}
				case '*': M[i][j] = BLOCKED; break;
				case 'O': {
					M[i][j] = FREE; 
					Oi = i; Oj = j;
					break;
				} 
				case 'I': {
					M[i][j] = FREE;
					Ii = i; Ij = j;
					break;
				}
				default: break;
			}
		}
	}
}	

inline int isValid(int i, int j) {
	if (i >= 0 && i < R && j >= 0 && j < C) return 1;
	return 0;
}
  
void findDist () {
	while (!Q.empty()) {
		int x = Q.front().first;
		int y = Q.front().second;
		Q.pop();	
		
		for (int i = 0; i < 4; ++i) {
			if (isValid(x+dx[i], y+dy[i]) && M[x+dx[i]][y+dy[i]] == FREE) {
				M[x+dx[i]][y+dy[i]] = M[x][y] + 1;
				if (M[x+dx[i]][y+dy[i]] > Max) Max = M[x+dx[i]][y+dy[i]];
				Q.push(make_pair(x+dx[i], y+dy[i]));
			}
		}
	}
}

bool bf(int d) {
	Q.push(make_pair(Ii, Ij));
	int visited[1005][1005] = {{0}};
	visited[Ii][Ij] = 1;
	
	while (!Q.empty()) {	
		int x = Q.front().first;
		int y = Q.front().second;
		Q.pop();
		
		if (x == Oi && y == Oj) return true;
		
		for (int i = 0; i < 4; ++i) {
			if (isValid(x+dx[i], y+dy[i]) && M[x+dx[i]][y+dy[i]] >= d && !visited[x+dx[i]][y+dy[i]]) {
				Q.push(make_pair(x+dx[i], y+dy[i]));
				visited[x+dx[i]][y+dy[i]] = 1;
			}
		}
	}
	
	return false; 
}

int solve () {
	int l = 0, r = Max, mid, sol;
	while (l <= r) {
		mid = (l + r) / 2;
		if (bf(mid)) {
			sol = mid;
			l = mid + 1;
		} else {
			r = mid - 1;			
		}
	}
	
	return sol;
}
			

int main (void) {
	freopen("barbar.in", "r", stdin);
	freopen("barbar.out", "w", stdout);
	
	read();
	
	findDist();
	
	int x = solve();
	if (!bf(0)) {
		printf("-1");
	} else {
		printf("%d", x);
	}
	
	return 0;
}