Cod sursa(job #2859341)

Utilizator db_123Balaban David db_123 Data 1 martie 2022 10:44:24
Problema Barbar Scor 90
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.56 kb
#include <fstream>
#include <vector>
#include <queue>
#include <bitset>

using namespace std;

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

struct Info{
    int x;
    int y;
};

int n,m;
int punctPlecareI,punctPlecareJ;
vector<vector<char>> ma;
queue<Info> Q;
vector<vector<bitset<1>>> visited;
vector<vector<int>> dist;
int dirI[4]={1,-1,0,0};
int dirJ[4]={0,0,1,-1};

void read(){
    cin>>n>>m;
    ma.resize(n+1,vector<char>(m+1));
    visited.resize(n+1,vector<bitset<1>>(m+1));
    dist.resize(n+1,vector<int>(m+1));
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            cin>>ma[i][j];
            if(ma[i][j]=='I'){
                punctPlecareI=i;
                punctPlecareJ=j;
            }
        }
    }
}

void leeDistDragoni(){
    int a,b,i,j;
    while(!Q.empty()){
        a=Q.front().x;
        b=Q.front().y;
        Q.pop();
        for(int u=0;u<4;u++){
            i=a+dirI[u];
            j=b+dirJ[u];
            if((i>0 && i<=n) && (j>0 && j<=m) && visited[i][j]==0 && ma[i][j]!='*'){
                dist[i][j]=dist[a][b]+1;
                Q.push({i,j});
                visited[i][j]=1;
            }
        }
    }
}

bool isValid(int distMid){
    while(!Q.empty()){
        Q.pop();
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            visited[i][j]=0;
        }
    }
    Q.push({punctPlecareI,punctPlecareJ});
    visited[punctPlecareI][punctPlecareJ]=1;

    if(dist[punctPlecareI][punctPlecareJ]<distMid){
        return false;
    }

    int a,b,i,j;
    while(!Q.empty()){
        a=Q.front().x;
        b=Q.front().y;
        Q.pop();

        if(ma[a][b]=='O'){
            return true;
        }

        for(int u=0;u<4;u++){
            i=a+dirI[u];
            j=b+dirJ[u];
            if((i>0 && i<=n) && (j>0 && j<=m) && visited[i][j]==0 && ma[i][j]!='D' && ma[i][j]!='*' && dist[i][j]>=distMid){
                // if(){
                //     return false;
                // }
                Q.push({i,j});
                visited[i][j]=1;
            }
        }
    }
    return false;
}

void solve(){
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(ma[i][j]=='D'){
                Q.push({i,j});
                visited[i][j]=1;
                dist[i][j]=0;
            }
        }
    }
    leeDistDragoni();

    int l=1,r=n,mid,sol=0;
    while(l<=r){
        mid=l+(r-l)/2;
        if(isValid(mid)){
            sol=max(sol,mid);
            l=mid+1;
        }
        else{
            r=mid-1;
        }
    }
    cout<<sol;
}

int main(){

    read();
    solve();   
    return 0;
}