Cod sursa(job #2540109)

Utilizator CosminMorarMorar Cosmin Andrei CosminMorar Data 6 februarie 2020 19:07:33
Problema Barbar Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.78 kb
#include <iostream>
#include <fstream>
#include <queue>
using namespace std;
ifstream fin("barbar.in");
ofstream fout("barbar.out");
int n, m;
int dist[1002][1002], distMin[1002][1002];
int di[] = {-1, 0, 1, 0}, dj[] = {0, 1, 0, -1};
queue<pair<int, int> > c, go;
pair<int, int> in, sf;

void readAndSet() {
    fin >> n >> m;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++) {
            char ch;
            fin >> ch;

            if (ch == '.') {
                dist[i][j] = 2000000000;
                distMin[i][j] = 0;
            }
            else if (ch == '*') {
                dist[i][j] = -1;
                distMin[i][j] = -1;
            } else if (ch == 'D') {
                dist[i][j] = 0;
                distMin[i][j] = -1;
                c.push(make_pair(i, j));
            } else if (ch == 'I') {
                dist[i][j] = 2000000000;
                distMin[i][j] = 0;
                in = make_pair(i, j);
            } else if (ch == 'O') {
                dist[i][j] = 2000000000;
                distMin[i][j] = 0;
                sf = make_pair(i, j);
            }
        }

    for (int i = 0; i <= n + 1; i++)
        dist[i][0] = dist[i][m + 1] = distMin[i][0] = distMin[i][m + 1] = -1;
    for (int j = 0; j <= m + 1; j++)
        dist[0][j] = dist[n + 1][j] = distMin[0][j] = distMin[n + 1][j] = -1;
}

void genDistFromDragons() {
    while (!c.empty()) {
        int iAct = c.front().first;
        int jAct = c.front().second;
        c.pop();

        for (int h = 0; h < 4; h++) {
            int iNew = iAct + di[h];
            int jNew = jAct + dj[h];

            if (dist[iNew][jNew] == -1)
                continue;

            if (dist[iAct][jAct] + 1 < dist[iNew][jNew]) {
                dist[iNew][jNew] = dist[iAct][jAct] + 1;
                c.push(make_pair(iNew, jNew));
            }
        }
    }
}

void genPath() {
    go.push(in);
    distMin[in.first][in.second] = dist[in.first][in.second];

    while (!go.empty()) {
        int iAct = go.front().first;
        int jAct = go.front().second;
        go.pop();

        for (int h = 0; h < 4; h++) {
            int iNew = iAct + di[h];
            int jNew = jAct + dj[h];

            if (distMin[iNew][jNew] == -1)
                continue;

            int newVal = min(distMin[iAct][jAct], dist[iNew][jNew]);

            if (newVal > distMin[iNew][jNew]) {
                distMin[iNew][jNew] = newVal;
                go.push(make_pair(iNew, jNew));
            }
        }
    }
}

int main() {
    readAndSet();
    genDistFromDragons();
    genPath();

    if (distMin[sf.first][sf.second] == 0)
        fout << -1;
    else
        fout << distMin[sf.first][sf.second];
    return 0;
}