Cod sursa(job #3343005)

Utilizator serbanbBrindescu Serban serbanb Data 26 februarie 2026 12:56:51
Problema Barbar Scor 50
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.78 kb
#include <fstream>
#include <queue>

using namespace std;

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

struct cell
{
    int dist;
    bool Dvisited = false;
    bool Pvisited = false;
    bool isWall = false;
    bool isExit = false;
};

int n,m;
cell prison[1005][1005];
queue<pair<int, int>> q;
int stPointi, stPointj;

void read()
{
    fin >> n >> m;
    for(int i = 0; i < n; ++i){
        for(int j = 0; j < m; ++j){
            char c;
            fin >> c;
            if(c == 'I'){
                stPointi = i;
                stPointj = j;
            }
            else if(c == 'D'){
                prison[i][j].Dvisited = true;
                prison[i][j].dist = 0;
                q.push(make_pair(i, j));
            }
            else if(c == '*'){
                prison[i][j].isWall = true;
            }
            else if(c == 'O'){
                prison[i][j].isExit = true;
            }
        }
    }
}

void bfs()
{
    while(!q.empty()){
        int i = q.front().first;
        int j = q.front().second;
        q.pop();
        if(!prison[i + 1][j].Dvisited && i + 1 < n){
            prison[i + 1][j].Dvisited = true;
            prison[i + 1][j].dist = prison[i][j].dist + 1;
            q.push(make_pair(i + 1, j));
        }
        if(!prison[i - 1][j].Dvisited && i > 0){
            prison[i - 1][j].Dvisited = true;
            prison[i - 1][j].dist = prison[i][j].dist + 1;
            q.push(make_pair(i - 1, j));
        }
        if(!prison[i][j + 1].Dvisited && j + 1 < m){
            prison[i][j + 1].Dvisited = true;
            prison[i][j + 1].dist = prison[i][j].dist + 1;
            q.push(make_pair(i, j + 1));
        }
        if(!prison[i][j - 1].Dvisited && j > 0){
            prison[i][j - 1].Dvisited = true;
            prison[i][j - 1].dist = prison[i][j].dist + 1;
            q.push(make_pair(i, j - 1));
        }
    }
}

bool path(int x, int y, int d)
{
    for(int i = 0; i < n; ++i){
        for(int j = 0; j < m; ++j){
            if(i == x && j == y){
                prison[i][j].Pvisited = true;
            }
            else{
                prison[i][j].Pvisited = false;
            }
        }
    }
    while(!q.empty()){
        q.pop();
    }
    q.push(make_pair(x, y));
    while(!q.empty()){
        int i = q.front().first;
        int j = q.front().second;
        if(prison[i][j].isExit){
            return true;
        }
        q.pop();
        if(!prison[i + 1][j].Pvisited && i + 1 < n && !prison[i + 1][j].isWall && prison[i + 1][j].dist >= d){
            prison[i + 1][j].Pvisited = true;
            q.push(make_pair(i + 1, j));
        }
        if(!prison[i - 1][j].Pvisited && i > 0 && !prison[i - 1][j].isWall && prison[i - 1][j].dist >= d){
            prison[i - 1][j].Pvisited = true;
            q.push(make_pair(i - 1, j));
        }
        if(!prison[i][j + 1].Pvisited && j + 1 < m && !prison[i][j + 1].isWall && prison[i][j + 1].dist >= d){
            prison[i][j + 1].Pvisited = true;
            q.push(make_pair(i, j + 1));
        }
        if(!prison[i][j - 1].Pvisited && j > 0 && !prison[i][j - 1].isWall && prison[i][j - 1].dist >= d){
            prison[i][j - 1].Pvisited = true;
            q.push(make_pair(i, j - 1));
        }
    }
    return false;
}

void binarySearch()
{
    int l = 0, r = 8;
    int ans;
    while(l <= r){
        int m = (l + r) / 2;
        if(path(stPointi, stPointj, m)){
            l = m + 1;
            ans = m;
        }
        else{
            r = m - 1;
        }
    }
    if(path(stPointi, stPointj, ans)){
        fout << ans;
    }
    else{
        fout << -1;
    }
}

int main()
{
    read();
    bfs();
    binarySearch();
    return 0;
}