Cod sursa(job #2692274)

Utilizator mex7Alexandru Valentin mex7 Data 1 ianuarie 2021 23:44:20
Problema Barbar Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.91 kb
#include <bits/stdc++.h>
#define ll long long
#define cin fin
#define cout fout
#define NEXTROW (row + dirX[i])
#define NEXTCOL (col + dirY[i])
using namespace std;
ifstream fin("barbar.in");
ofstream fout("barbar.out");
bitset <1001> reached[1001];
int n, m, distToDragon[1001][1001], result[1001][1001];
int dirX[] = {0, 1, 0, -1};
int dirY[] = {1, 0, -1, 0};
string grid[1001];

struct comp {
    bool operator()(tuple <int, int, int> a, tuple <int, int, int> b) {
        return (get <2> (a)) < (get <2> (b));
    }
};

int main() {
    cin >> n >> m;
    for (int i = 0; i < n; i++)
        cin >> grid[i];

    pair <int, int> entrance, exit;
    queue <tuple <int, int, int> > dragonDist;
    for (int i = 0; i < n; i++) 
        for (int j = 0; j < m; j++)
            if (grid[i][j] == 'O')
                exit = make_pair(i, j);
            else if (grid[i][j] == 'I')
                entrance = make_pair(i, j);
            else if (grid[i][j] == 'D')
                dragonDist.push(make_tuple(i, j, 0));

    int row, col, cost;
    while (!dragonDist.empty()) {
        tie(row, col, cost) = dragonDist.front();
        dragonDist.pop();

        if (!reached[row][col]) {
            distToDragon[row][col] = cost;
            reached[row][col] = 1;
            for (int i = 0; i < 4; i++)
                if (NEXTROW >= 0 && NEXTROW < n && NEXTCOL >= 0 && NEXTCOL < m) 
                    if (grid[NEXTROW][NEXTCOL] != '*' && grid[NEXTROW][NEXTCOL] != 'D') 
                        if (!reached[NEXTROW][NEXTCOL])
                            dragonDist.push(make_tuple(NEXTROW, NEXTCOL, cost + 1));
        }
    }
    
    for (int i = 0; i < n; i++)
        reached[i].reset();

    priority_queue <tuple <int, int, int>, vector <tuple <int, int, int> >, comp> bestChoice;
    bestChoice.push(make_tuple(entrance.first, entrance.second, distToDragon[entrance.first][entrance.second]));
    while (!bestChoice.empty()) {
        tie(row, col, cost) = bestChoice.top();
        bestChoice.pop();

        if (!reached[row][col]) {
            reached[row][col] = 1;
            result[row][col] = cost;
            for (int i = 0; i < 4; i++)
                if (NEXTROW >= 0 && NEXTROW < n && NEXTCOL >= 0 && NEXTCOL < m)
                    if (grid[NEXTROW][NEXTCOL] != 'D' && grid[NEXTROW][NEXTCOL] != '*') 
                        if (!reached[NEXTROW][NEXTCOL])
                            bestChoice.push(make_tuple(NEXTROW, NEXTCOL, min(cost, distToDragon[NEXTROW][NEXTCOL])));
        }

        if (row == exit.first && col == exit.second) {
            cout << cost;
            return 0;
        }
    }

    cout << -1;
    //cout << exit.first << ' ' << exit.second;
    // for (int i = 0; i < n; i++) {
    //     for (int j = 0; j < m; j++)
    //         if (grid[i][j] != '*' && grid[i][j] != 'D')
    //             cout << result[i][j];
    //         else
    //             cout << 'P';
    //     cout << '\n';
    // }
    return 0;
}