Pagini recente » Promo | Cod sursa (job #940168) | Profil CNMV_SERITAN_DUMITRESCU_MUNTEANU | Autentificare | Cod sursa (job #2017550)
#include <iostream>
#include <fstream>
#include <queue>
#include <vector>
using namespace std;
ifstream in("barbar.in");
ofstream out("barbar.out");
struct Waypoint {
int x, y, d;
};
struct Cell {
int x, y;
};
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, 1, 0, -1};
int r, c;
Cell start, ex;
int dist[1001][1001], best[1001][1001];
char a[1001][1001];
queue<Cell> q;
queue<Waypoint> road;
void calculate_distances() {
while (!q.empty()) {
Cell w = q.front(); q.pop();
int x = w.x, y = w.y;
for (int k = 0; k < 4; ++k) {
int i = x + dx[k];
int j = y + dy[k];
if (i >= 1 && i <= r && j >= 1 && j <= c) {
if ((a[i][j] == '.' || a[i][j] == 'I' || a[i][j] == 'O') && dist[i][j] == 0) {
dist[i][j] = dist[x][y] + 1;
q.push({i, j});
}
}
}
}
}
void solve() {
road.push({start.x, start.y, dist[start.x][start.y]});
while (!road.empty()) {
Waypoint w = road.front(); road.pop();
int x = w.x, y = w.y, d = w.d;
for (int k = 0; k < 4; ++k) {
int i = x + dx[k];
int j = y + dy[k];
if (i >= 1 && i <= r && j >= 1 && j <= c) {
if (dist[i][j] != 0) {
bool push = false;
if (best[i][j] == 0) { // first time here
push = true;
best[i][j] = min(d, dist[i][j]);
} else { // not first time
if (d > dist[i][j]) continue; // bigger dist than biggest possible
// else
if (d < dist[i][j]) {
if (d > best[i][j]) {
push = true;
best[i][j] = d;
}
}
}
if (i == ex.x && j == ex.y) continue;
if (push) {
road.push({i, j, best[i][j]});
}
}
}
}
}
}
int main()
{
in >> r >> c;
for (int i = 1; i <= r; ++i) {
for (int j = 1; j <= c; ++j) {
in >> a[i][j];
if (a[i][j] == 'I') {
start = {i, j};
} else if (a[i][j] == 'O') {
ex = {i, j};
} else if (a[i][j] == 'D') {
q.push({i, j});
}
}
}
calculate_distances();
solve();
if (best[ex.x][ex.y] == 0) out << -1; else out << best[ex.x][ex.y];
/*for (int i = 1; i <= r; ++i) {
for (int j = 1; j <= c; ++j) {
if (dist[i][j] == 0) {
cout << a[i][j] << " ";
} else {
cout << best[i][j] << " ";
}
}
cout << endl;
}*/
return 0;
}