Cod sursa(job #2083204)

Utilizator bciobanuBogdan Ciobanu bciobanu Data 7 decembrie 2017 11:20:33
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.15 kb
#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() {
    ifstream cin("barbar.in");
    ofstream cout("barbar.out");
    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];
            }
        }
    }
 
    while (not dq.empty()) {
        const auto poz = dq.front(); dq.pop_front();
        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;
            }
        }
    }
}