Cod sursa(job #2703544)

Utilizator gasparrobert95Gaspar Robert Andrei gasparrobert95 Data 8 februarie 2021 18:54:35
Problema Barbar Scor 90
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.63 kb
#include <bits/stdc++.h>
#define ll long long
using namespace std;
ifstream fin("barbar.in");
ofstream fout("barbar.out");
int n, m, startx, starty, sfx, sfy, mt[1005][1005], dist[1005][1005];
int ox[] = {-1, 0, 1, 0}, oy[] = {0, 1, 0, -1};
bool inpq[1005][1005], block[1005][1005];
queue < pair <int, int> > q;

struct cmp {
    bool operator() (pair <int, int> a, pair <int, int> b) {
        return dist[a.first][a.second] < dist[b.first][b.second];
    }
};

priority_queue <pair <int, int>, vector < pair <int, int> >, cmp> pq;

void readInput() {
    fin >> n >> m;
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= m; ++j) {
            char el;
            fin >> el;
            if (el == 'D') {
                block[i][j] = true;
                q.push({i, j});
            }
            if (el == '*')
                mt[i][j] = -1;
            if (el == 'I')
                startx = i, starty = j;
            if (el == 'O')
                sfx = i, sfy = j;
        }
    return;
}

void leeDragoni() {
    while (!q.empty()) {
        int x = q.front().first, y = q.front().second;
        q.pop();
        for (int i = 0; i < 4; ++i) {
            int a = x + ox[i], b = y + oy[i];
            if (!block[a][b] && a >= 1 && a <= n && b <= m && b >= 1 && dist[a][b] == 0) {
                dist[a][b] = dist[x][y] + 1;
                q.push({a, b});
            }
        }
    }
    return;
}

void dfs(int x, int y) {
    if (x < 1 || x > n || y < 1 || y > m)
        return;
    mt[x][y] = -2;
    for (int i = 0; i < 4; ++i)
        if (mt[x + ox[i]][y + oy[i]] == 0 || (x + ox[i] == sfx && y + oy[i] == sfy))
            dfs(x + ox[i], y + oy[i]);
    return;
}

void lee() {
    mt[sfx][sfy] = -1;
    mt[startx][starty] = dist[startx][starty];
    pq.push({startx, starty});
    while (!pq.empty() && mt[sfx][sfy] == -1) {
        int x = pq.top().first, y = pq.top().second;
        pq.pop();
        inpq[x][y] = false;
        for (int i = 0; i < 4; ++i) {
            int a = x + ox[i], b = y + oy[i], minim = min(mt[x][y], dist[a][b]);
            if (a >= 1 && a <= n && b >= 1 && b <= m && (mt[a][b] != -1 || (a == sfx && b == sfy)) && minim > mt[a][b]) {
                mt[a][b] = minim;
                if (!inpq[a][b]) {
                    inpq[a][b] = true;
                    pq.push({a, b});
                }
            }
        }
    }
    dfs(startx, starty);
    if (mt[sfx][sfy] == -2)
        fout << 0;
    else
        fout << mt[sfx][sfy];
    return;
}

int main() {
    readInput();
    leeDragoni();
    lee();
    return 0;
}