Pagini recente » Cod sursa (job #520094) | Diferente pentru runda/redsnow_3 intre reviziile 51 si 50 | Cod sursa (job #1694443) | Monitorul de evaluare | Cod sursa (job #2073856)
//#include <debug.hpp>
#include <cassert>
#include <functional>
#include <queue>
#include <vector>
#include <deque>
#include <iostream>
#include <fstream>
using namespace std;
constexpr int kInf = 0x3f3f3f3f;
constexpr int kDir[4][2] = {{-1, 0}, {0, -1}, {1, 0}, {0, 1}};
int main() {
#ifdef INFOARENA
ifstream cin("barbar.in");
ofstream cout("barbar.out");
#endif
int n, m; cin >> n >> m;
vector<string> mat(n);
for (auto& row : mat) {
cin >> row;
}
vector<vector<int>> mn_distances(n, vector<int>(m, kInf));
auto BuildMinDistances = [&]() {
queue<pair<int, int>> dragons;
for (int i = 0; i < n; i += 1) {
for (int j = 0; j < m; j += 1) {
if (mat[i][j] == 'D') {
mn_distances[i][j] = 0;
dragons.emplace(i, j);
}
}
}
while (not dragons.empty()) {
const auto dragon = dragons.front(); dragons.pop();
for (int dir = 0; dir < 4; dir += 1) {
const auto neigh = make_pair(dragon.first + kDir[dir][0],
dragon.second + kDir[dir][1]);
if (neigh.first < 0 or neigh.second < 0
or neigh.first >= n or neigh.second >= m
or mat[neigh.first][neigh.second] == '*'
or mn_distances[neigh.first][neigh.second] != kInf) {
continue;
}
mn_distances[neigh.first][neigh.second] = mn_distances[dragon.first][dragon.second] + 1;
dragons.push(neigh);
}
}
};
BuildMinDistances();
deque<pair<int, int>> dq;
vector<vector<int>> mn_cost(n, vector<int>(m, kInf));
for (int i = 0; i < n; i += 1) {
for (int j = 0; j < m; j += 1) {
if (mat[i][j] == 'I') {
dq.emplace_back(i, j);
mn_cost[i][j] = mn_distances[i][j];
}
}
}
assert(dq.size() == 1);
while (not dq.empty()) {
const auto poz = dq.front(); dq.pop_front();
//Debug(poz);
for (int dir = 0; dir < 4; dir += 1) {
const auto neigh = make_pair(poz.first + kDir[dir][0],
poz.second + kDir[dir][1]);
if (neigh.first < 0 or neigh.second < 0
or neigh.first >= n or neigh.second >= m
or mat[neigh.first][neigh.second] == '*'
or mn_cost[neigh.first][neigh.second] != kInf) {
continue;
}
if (mn_distances[neigh.first][neigh.second] >= mn_cost[poz.first][poz.second]) {
mn_cost[neigh.first][neigh.second] = mn_cost[poz.first][poz.second];
dq.push_front(neigh);
} else {
mn_cost[neigh.first][neigh.second] = mn_distances[neigh.first][neigh.second];
dq.push_back(neigh);
}
}
}
for (int i = 0; i < n; i += 1) {
for (int j = 0; j < m; j += 1) {
if (mat[i][j] == 'O') {
if (mn_cost[i][j] == kInf) {
mn_cost[i][j] = -1;
}
cout << mn_cost[i][j] << endl;
return 0;
}
}
}
}