Cod sursa(job #2307904)

Utilizator Alex_BubBuburuzan Alexandru Alex_Bub Data 25 decembrie 2018 20:44:10
Problema Barbar Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.2 kb
#include <fstream>
#include <queue>
#include <utility>
#include <cstring>

using namespace std;

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

const int NMax = 1000;

int N, M, l1, c1, l2, c2, D[NMax + 5][NMax + 5], Lee[NMax + 5][NMax + 5];

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

bool Viz[NMax + 5][NMax + 5];

char k;

queue <pair<int, int> > DQ;

inline bool valid(int i, int j) {
    return (i && j && i <= N && j <= M);
}

void MakeDist()
{
    while(!DQ.empty()) {
        int l = DQ.front().first, c = DQ.front().second;

        for(int i = 0; i < 4; i++) {
            int nl = l + dl[i], nc = c + dc[i];

            if(Lee[nl][nc] != 1 && !D[nl][nc] && valid(nl, nc)) {
                D[nl][nc] = D[l][c] + 1;
                DQ.push({nl, nc});
            }
        }
        DQ.pop();
    }
}

bool Check(int T) {
    memset(Viz, 0, sizeof(Viz));

    queue <pair<int, int> > Q;

    Q.push({l1, c1});
    Viz[l1][c1] = true;

    if(D[l1][c1] < T) return 0;

    while(!Q.empty()) {
        int l = Q.front().first, c = Q.front().second;

        for(int i = 0; i < 4; i++) {
            int nl = l + dl[i], nc = c + dc[i];

            if(valid(nl, nc) && !Viz[nl][nc] && D[nl][nc] >= T) {
                Viz[nl][nc] = true;
                Q.push({nl,nc});
            }
        }
        if(Viz[l2][c2]) return 1;

        Q.pop();
    }
    return 0;
}

int Solve() {
    int st = 0, dr = NMax * NMax + 5, ans = -1;

    while(st <= dr) {
        int m = (st + dr) / 2;

        if(Check(m))
            ans = m, st = m + 1;
        else
            dr = m - 1;
    }

    return ans;
}

int main()
{
    fin >> N >> M;

    for(int i = 1; i <= N; i++) {
        for(int j = 1; j <= M; j++) {
            fin >> k;

            if(k == 'D')
                DQ.push({i, j}), Lee[i][j] = 1;

            if(k == '*')
                Lee[i][j] = 2, D[i][j] = -1;

            if(k == 'I')
                l1 = i, c1 = j;

            if(k == 'O')
                l2 = i, c2 = j;
        }
    }
    MakeDist();

    fout << Solve() << '\n';

    fout.close();
    fin.close();

    return 0;
}