Cod sursa(job #2695969)

Utilizator vladdudauDudau Vlad vladdudau Data 14 ianuarie 2021 23:47:47
Problema Barbar Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.24 kb
#include <fstream>
#include <queue>
#include <bitset>

using namespace std;

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

const int MX_SZ = 1005;
const int INF = 1<<30;
const int DX[4] = {-1, 0, 1,  0};
const int DY[4] = { 0, 1, 0, -1};

struct xy{
    int x,y;
};

int N,M,d[MX_SZ][MX_SZ],l=INF,r,ans;
char m[MX_SZ][MX_SZ];
xy st, en;
queue <xy> q;
bitset <MX_SZ> bs[MX_SZ];

void reset(){
    for(int i = 1; i <= N; ++i)
        for(int j = 1; j <= M; ++j)
            bs[i][j] = 0;
}

void read(){
    in>>N>>M;
    for(int i = 1; i <= N; ++i)
        for(int j = 1; j <= M; ++j){
            in>>m[i][j];
            d[i][j] = INF;
            if(m[i][j] == 'I') st = {i, j};
            else if(m[i][j] == 'D') q.push({i, j}), d[i][j] = 0;
            else if(m[i][j] == 'O') en = {i, j};
        }
}

bool bfs(const int &p){
    reset();
    q.push(st);
    bs[st.x][st.y] = 1;

    if(d[st.x][st.y] < p) return 0;

    while(!q.empty()){
        xy f = q.front();
        q.pop();

        for(int i = 0; i < 4; ++i){
            xy nx = {f.x + DX[i], f.y + DY[i]};
            if((m[nx.x][nx.y] == '.' || m[nx.x][nx.y] == 'O') && d[nx.x][nx.y] >= p && bs[nx.x][nx.y] == 0){

                bs[nx.x][nx.y] = 1;
                q.push(nx);
            }
        }
    }

    return bs[en.x][en.y] == 1 ? 1 : 0;
}

int main(){
    ios::sync_with_stdio(0);
    read();

    for(int i = 0; i <= M + 1; ++i)
        m[0][i] = m[N + 1][0] = '*';

    for(int i = 0; i <= N + 1; ++i)
        m[i][0] = m[0][M + 1] = '*';

    while(!q.empty()){
        xy f = q.front();
        q.pop();

        for(int i = 0; i < 4; ++i){
            xy nx = {f.x + DX[i], f.y + DY[i]};
            if(d[nx.x][nx.y] > d[f.x][f.y] + 1 && m[nx.x][nx.y] != '*'){
                d[nx.x][nx.y] = d[f.x][f.y] + 1;
                r = max(r, d[nx.x][nx.y]);
                l = min(l, d[nx.x][nx.y]);
                q.push(nx);
            }
        }
    }

    while(l <= r){
        int m = (l + r) / 2;

        if(bfs(m)){
            ans = max(ans, m);
            ++l;
        }
        else{
            --r;
        }
    }

    if(!ans) out<<-1;
    else out<<ans;

    return 0;
}