Cod sursa(job #2712684)

Utilizator iancupoppPopp Iancu Alexandru iancupopp Data 26 februarie 2021 12:06:28
Problema Barbar Scor 30
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.69 kb
#include <fstream>
#include <queue>
#include <stack>

using namespace std;

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

bool obs[N + 2][N + 2], viz[N + 1][N + 1];
int d[N + 1][N + 1], nl, nc, xi, yi, xf, yf, maxi;
queue<pair<int, int>> q;
stack<pair<int, int>> st;

void bordare() {
    for (int i = 0; i <= nl + 1; ++i)
        obs[i][0] = obs[i][nc + 1] = true;
    for (int j = 1; j <= nc; ++j)
        obs[0][j] = obs[nc][j] = true;
}

void lee() {
    int l, c;
    while (!q.empty()) {
        auto crt = q.front();
        q.pop();
        for (int i = 0; i < 4; ++i) {
            l = crt.first + dx[i];
            c = crt.second + dy[i];
            if (!obs[l][c] && !d[l][c]) {
                d[l][c] = d[crt.first][crt.second] + 1;
                q.push({ l, c });
            }
        }
    }
}

void clear() {
    while (!st.empty())
        st.pop();
    for (int i = 1; i <= nl; ++i)
        for (int j = 1; j <= nc; ++j)
            viz[i][j] = false;
}

void getmax() {
    for (int i = 1; i <= nl; ++i)
        for (int j = 1; j <= nc; ++j)
            maxi = max(maxi, d[i][j]);
}

bool test(int val) {
    clear();
    st.push({ xi, yi });
    viz[xi][yi] = true;

    int l, c;
    bool found = false;
    while (!st.empty()) {
        auto crt = st.top();
        if (crt.first == xf && crt.second == yf) {
            found = true;
            break;
        }
        st.pop();
        for (int i = 0; i < 4; ++i) {
            l = crt.first + dx[i];
            c = crt.second + dy[i];
            if (!viz[l][c] && d[l][c] >= val) {
                viz[l][c] = true;
                st.push({ l, c });
            }
        }
    }
    return found;
}

int cbin() {
    int st = 1, dr = maxi, m;
    while (st < dr) {
        m = (st + dr) / 2;
        if (!test(m))
            dr = m;
        else
            st = m + 1;
    }
    return st - 1;
}

int main() {
    ifstream in("barbar.in");
    ofstream out("barbar.out");

    char c;
    in >> nl >> nc;
    for (int i = 1; i <= nl; ++i)
        for (int j = 1; j <= nc; ++j) {
            in >> c;
            if (c == 'D')
                q.push({ i, j });
            else if (c == '*')
                obs[i][j] = true;
            else if (c == 'I') {
                xi = i;
                yi = j;
            }
            else if (c == 'O') {
                xf = i;
                yf = j;
            }
        }
    bordare();
    lee();
    getmax();
    int rez = cbin();
    if (rez)
        out << rez;
    else
        out << "-1";

    in.close();
    out.close();
    return 0;
}