Cod sursa(job #3306756)

Utilizator unknowuserBarat David Pavel unknowuser Data 13 august 2025 15:16:34
Problema Barbar Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.79 kb
#include <bits/stdc++.h>
using namespace std;

static const int INF = 1'000'000'000;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

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

    int R, C;
    fin >> R >> C;
    vector<string> grid(R);
    for (int i = 0; i < R; ++i) {
        fin >> grid[i];
    }

    auto in_bounds = [&](int r, int c) {
        return r >= 0 && r < R && c >= 0 && c < C;
    };

    const int dr[4] = {-1, 1, 0, 0};
    const int dc[4] = {0, 0, -1, 1};

    auto id = [&](int r, int c) { return r * C + c; };

    vector<int> dist(R * C, INF);
    vector<char> is_wall(R * C, 0);

    queue<pair<int,int>> q;
    int sr = -1, sc = -1, tr = -1, tc = -1;

    for (int r = 0; r < R; ++r) {
        for (int c = 0; c < C; ++c) {
            char ch = grid[r][c];
            if (ch == '*') {
                is_wall[id(r,c)] = 1;
                dist[id(r,c)] = -1;
            } else if (ch == 'D') {
                dist[id(r,c)] = 0;
                q.emplace(r, c);
            } else if (ch == 'I') {
                sr = r; sc = c;
            } else if (ch == 'O') {
                tr = r; tc = c;
            }
        }
    }

    while (!q.empty()) {
        auto [r, c] = q.front(); q.pop();
        int dcur = dist[id(r,c)];
        for (int k = 0; k < 4; ++k) {
            int nr = r + dr[k], nc = c + dc[k];
            if (!in_bounds(nr, nc)) continue;
            int nid = id(nr, nc);
            if (is_wall[nid]) continue;
            if (dist[nid] > dcur + 1) {
                dist[nid] = dcur + 1;
                q.emplace(nr, nc);
            }
        }
    }

    auto can = [&](int T) -> bool {
        if (sr == -1 || tr == -1) return false;
        int sid = id(sr, sc);
        int tid = id(tr, tc);
        if (is_wall[sid] || is_wall[tid]) return false;
        if (dist[sid] < T || dist[tid] < T) return false;

        queue<int> qq;
        vector<char> vis(R * C, 0);
        qq.push(sid);
        vis[sid] = 1;

        while (!qq.empty()) {
            int u = qq.front(); qq.pop();
            if (u == tid) return true;
            int ur = u / C, uc = u % C;
            for (int k = 0; k < 4; ++k) {
                int vr = ur + dr[k], vc = uc + dc[k];
                if (!in_bounds(vr, vc)) continue;
                int vid = id(vr, vc);
                if (vis[vid]) continue;
                if (is_wall[vid]) continue;
                if (dist[vid] < T) continue;
                vis[vid] = 1;
                qq.push(vid);
            }
        }
        return false;
    };

    if (!can(0)) {
        fout << -1 << '\n';
        return 0;
    }

    int lo = 0, hi = R * C;
    while (lo < hi) {
        int mid = lo + (hi - lo + 1) / 2;
        if (can(mid)) lo = mid;
        else hi = mid - 1;
    }

    fout << lo << '\n';
    return 0;
}