Cod sursa(job #1619485)

Utilizator cautionPopescu Teodor caution Data 28 februarie 2016 16:34:26
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.18 kb
#include <fstream>
#include <queue>
#include <utility>

constexpr int kMaxR = 1000;
constexpr int kMaxC = 1000;
constexpr int kEmpty = -2;
constexpr int kWall = -1;


int map[kMaxR+2][kMaxC+2];
bool visited[kMaxR+2][kMaxC+2];
int main()
{
    std::ifstream in("barbar.in");
    std::ofstream out("barbar.out");
    int r, c, in_i = 1, in_j = 1, out_i = 1, out_j = 1;
    std::queue<std::pair<int, int> > Q;

    //read and arrange
    in>>r>>c;
    for(int j = 0; j <= c+1; ++j) map[0][j] = kWall;
    for(int i = 1; i <= r; ++i) {
        char cx;
        map[i][0] = kWall;
        for(int j = 1; j <= c; ++j) {
            in>>cx;
            switch(cx) {
            case 'I': in_i = i; in_j = j; map[i][j] = kEmpty; break;
            case 'O': out_i = i; out_j = j; map[i][j] = kEmpty; break;
            case '.': map[i][j] = kEmpty; break;
            case '*': map[i][j] = kWall; break;
            case 'D': Q.push(std::make_pair(i, j)); map[i][j] = 0; break;
            default: --j;
            }
        }
        map[i][c+1] = kWall;
    }
    for(int j = 0; j <= c+1; ++j) map[r+1][j] = kWall;

    //bfs to obtain distance from dragons
    while(!Q.empty()) {
        int i = Q.front().first;
        int j = Q.front().second;
        Q.pop();
        if(map[i-1][j] == kEmpty) {
            map[i-1][j] = map[i][j]+1;
            Q.push(std::make_pair(i-1, j));
        }
        if(map[i+1][j] == kEmpty) {
            map[i+1][j] = map[i][j]+1;
            Q.push(std::make_pair(i+1, j));
        }
        if(map[i][j-1] == kEmpty) {
            map[i][j-1] = map[i][j]+1;
            Q.push(std::make_pair(i, j-1));
        }
        if(map[i][j+1] == kEmpty) {
            map[i][j+1] = map[i][j]+1;
            Q.push(std::make_pair(i, j+1));
        }
    }

    //do dijkstra
    auto comp = [](std::pair<int, int> x, std::pair<int, int> y) {
        return map[x.first][x.second] < map[y.first][y.second];
    };
    std::priority_queue<std::pair<int, int>, std::vector<std::pair<int, int> >, decltype(comp)> priorityQ(comp);
    priorityQ.push(std::make_pair(in_i, in_j));
    visited[in_i][in_j] = true;
    while(!priorityQ.empty()) {
        int i = priorityQ.top().first;
        int j = priorityQ.top().second;
        priorityQ.pop();
        if(i == out_i && j == out_j) break;
        if(map[i-1][j] != kWall && !visited[i-1][j]) {
            map[i-1][j] = std::min(map[i-1][j], map[i][j]);
            priorityQ.push(std::make_pair(i-1, j));
            visited[i-1][j] = true;
        }
        if(map[i+1][j] != kWall && !visited[i+1][j]) {
            map[i+1][j] = std::min(map[i+1][j], map[i][j]);
            priorityQ.push(std::make_pair(i+1, j));
            visited[i+1][j] = true;
        }
        if(map[i][j-1] != kWall && !visited[i][j-1]) {
            map[i][j-1] = std::min(map[i][j-1], map[i][j]);
            priorityQ.push(std::make_pair(i, j-1));
            visited[i][j-1] = true;
        }
        if(map[i][j+1] != kWall && !visited[i][j+1]) {
            map[i][j+1] = std::min(map[i][j+1], map[i][j]);
            priorityQ.push(std::make_pair(i, j+1));
            visited[i][j+1] = true;
        }
    }
    if(visited[out_i][out_j]) out<<map[out_i][out_j]<<'\n';
    else out<<"-1\n";
}