Cod sursa(job #3338998)

Utilizator parus_majorParus Major parus_major Data 5 februarie 2026 17:21:24
Problema Barbar Scor 70
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.19 kb
#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>
#include <climits>

using namespace std;

ifstream fin("barbar.in");
ofstream fout("barbar.out");

const int MAXN = 1002;

vector<int> dx = { -1, 1, 0, 0};
vector<int> dy = { 0, 0, -1, 1 };

char dungeon[MAXN][MAXN];
bool visited[MAXN][MAXN];
int dist[MAXN][MAXN], ans[MAXN][MAXN];
int N, M;

int q_x[MAXN * MAXN], q_y[MAXN * MAXN];
int q_size;

int start_x, start_y, end_x, end_y;

int q2_x[MAXN * MAXN], q2_y[MAXN * MAXN];
int q2_size;

static bool check(int x, int y) {
    return (x >= 1) && (x <= N) && (y >= 1) && (y <= M) && (dungeon[x][y] != '*');
}

static void expand(int X, int Y) {
    q2_size = 1;
    q2_x[0] = X;
    q2_y[0] = Y;
    visited[X][Y] = true;
    ans[X][Y] = dist[X][Y];

    for (int t = 0; t < q2_size; ++t) {
        for (int i = 0; i < 4; ++i) {
            const int x = q2_x[t] + dx[i];
            const int y = q2_y[t] + dy[i];

            if (!check(x, y)) continue;
            if (visited[x][y]) continue;

            if (dist[x][y] < dist[X][Y]) continue;

            visited[x][y] = true;
            ans[x][y] = dist[X][Y];
            q2_x[q2_size] = x;
            q2_y[q2_size] = y;
            ++q2_size;
        }
    }
}
int main()
{
    fin >> N >> M;
    for (int i = 1; i <= N; ++i) {
        for (int j = 1; j <= M; ++j) {
            fin >> dungeon[i][j];
        }
    }

    for (int i = 1; i <= N; ++i) {
        for (int j = 1; j <= M; ++j) {
            if (dungeon[i][j] == 'D') {
                q_x[q_size] = i;
                q_y[q_size] = j;
                visited[i][j] = true;
                dist[i][j] = 0;
                ++q_size;
            }
            if (dungeon[i][j] == 'I') {
                start_x = i;
                start_y = j;
            }
            if (dungeon[i][j] == 'O') {
                end_x = i;
                end_y = j;
            }
        }
    }

    for (int idx = 0; idx < q_size; ++idx) {
        for (int i = 0; i < 4; ++i) {
            const int x = q_x[idx] + dx[i];
            const int y = q_y[idx] + dy[i];
            if (!check(x, y)) continue;
            if (visited[x][y]) continue;

            visited[x][y] = true;
            dist[x][y] = dist[q_x[idx]][q_y[idx]] + 1;
            q_x[q_size] = x;
            q_y[q_size] = y;
            ++q_size;
        }
    }

    for (int i = 1; i <= N; ++i) {
        for (int j = 1; j <= M; ++j) {
            visited[i][j] = false;
        }
    }

    for (int idx = q_size - 1; idx >= 0; --idx) {
        if (visited[q_x[idx]][q_y[idx]]) continue;

        bool has_visited_neighbour = (q_x[idx] == start_x && q_y[idx] == start_y);
        for (int i = 0; i < 4; ++i) {
            const int x = q_x[idx] + dx[i];
            const int y = q_y[idx] + dy[i];
            if (!check(x, y)) continue;

            has_visited_neighbour |= visited[x][y];
        }

        if (!has_visited_neighbour) continue;

        expand(q_x[idx], q_y[idx]);
    }

    if (!visited[end_x][end_x]) {
        fout << '-1';
        return 0;
    }

    fout << ans[end_x][end_y];

    return 0;
}