Cod sursa(job #2562965)

Utilizator oldatlantianSerban Cercelescu oldatlantian Data 29 februarie 2020 20:44:29
Problema Barbar Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.05 kb
#include <bits/stdc++.h>
#define x first
#define y second
using namespace std;

ifstream fi("barbar.in");
ofstream fo("barbar.out");

using pii = pair<int, int>;

const int dx[] = {0, 0, 1, -1};
const int dy[] = {1, -1, 0, 0};
const int N = 1005;

char mx[N][N];
int dist[N][N];
bool f[N][N];

int n, m, ans;
deque<pii> drakq, distq;
pii hero, treasure;

int main() {
    fi >> n >> m;
    for (int i = 1; i <= n; ++i) {
        fi >> (mx[i] + 1);
        for (int j = 1; j <= m; ++j) {
            dist[i][j] = 1e9;
            if (mx[i][j] == 'D') {
                drakq.emplace_back(i, j);
                dist[i][j] = 0;
            }
            if (mx[i][j] == 'I')
                hero = {i, j};
            if (mx[i][j] == 'O')
                treasure = {i, j};
        }
    }

    for (int i = 0; i <= n + 1; ++i)
        mx[i][0] = mx[i][m + 1] = '*';
    for (int j = 0; j <= m + 1; ++j)
        mx[0][j] = mx[n + 1][j] = '*';

    while (!drakq.empty()) {
        pii now = drakq.front();
        drakq.pop_front();
        for (int dir = 0; dir < 4; ++dir) {
            int nx = now.x + dx[dir];
            int ny = now.y + dy[dir];
            if (mx[nx][ny] != '*' && dist[nx][ny] == 1e9) {
                dist[nx][ny] = dist[now.x][now.y] + 1;
                drakq.push_back(pii(nx, ny));
            }
        }
    }

    ans = dist[hero.x][hero.y];
    f[hero.x][hero.y] = true;
    distq.push_back(hero);
    while (!distq.empty()) {
        pii now = distq.front();
        distq.pop_front();

        ans = min(ans, dist[now.x][now.y]);
        if (now == treasure) {
            fo << ans << endl;
            exit(0);
        }

        for (int dir = 0; dir < 4; ++dir) {
            int nx = now.x + dx[dir];
            int ny = now.y + dy[dir];
            if (mx[nx][ny] != '*' && !f[nx][ny]) {
                f[nx][ny] = true;
                if (dist[nx][ny] >= ans)
                    distq.push_front(pii(nx, ny));
                else
                    distq.push_back(pii(nx, ny));
            }
        }
    }

    fo << "-1\n";

    return 0;
}