Cod sursa(job #2957391)

Utilizator Utucora2017Nicolae Utucora2017 Data 22 decembrie 2022 15:31:46
Problema Barbar Scor 40
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.59 kb
#include<fstream>
#include<queue>
using namespace std;
ifstream cin("barbar.in");
ofstream cout("barbar.out");
pair<int,int> dragoni[100001];
int n,m,distante,cnt,cntdrag,xstart,ystart,xfinal,yfinal,minim,sol,ok;
int a[1001][1001],b[1001][1001],c[1001][1001],dx[]={0,0,-1,1},dy[]={1,-1,0,0},viz[1001][1001];
bool inmat(int x, int y){
    return x>=1&&x<=n&&y>=1&&y<=m;
}
void rmat(){
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            b[i][j]=0;
}
void rmat2(){
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            viz[i][j]=0;
}
void lee(int xs, int ys){
    queue<pair<int,int> >q;
    b[xs][ys]=1;
    q.push(make_pair(xs,ys));
    while(!q.empty()){
        int x=q.front().first,y=q.front().second;
        q.pop();
        for(int i=0;i<4;i++){
            int xnou=dx[i]+x,ynou=dy[i]+y;
            if(a[xnou][ynou]!=0&&inmat(xnou,ynou)&&b[xnou][ynou]==0){
                b[xnou][ynou]=b[x][y]+1;
                if(a[xnou][ynou]>0)
                    q.push(make_pair(xnou,ynou));
            }
        }
    }
}
void lee2(){
    queue<pair<int,int> > q;
    q.push(make_pair(xstart,ystart));
    viz[xstart][ystart]=1;
    //cout<<ok<<" ";
    while(!q.empty()&&!ok){
        int x=q.front().first,y=q.front().second;
        q.pop();
        for(int i=0;i<4;i++){
            int xnou=x+dx[i],ynou=dy[i]+y;
            //cout<<"t"<<" "<<xnou<<" "<<ynou<<"\n";
            if(inmat(xnou,ynou)&&a[xnou][ynou]&&!viz[xnou][ynou]){
              //  cout<<"t"<<" "<<xnou<<" "<<ynou<<"\n";
                if(c[xnou][ynou]==9999999){
                    lee(xnou,ynou);
                    for(int j=1;j<=cntdrag;j++)
                       c[xnou][ynou]=min(c[xnou][ynou],b[dragoni[j].first][dragoni[j].second]-1);
                    rmat();
                }
                //cout<<xnou<<" "<<ynou<<"\n";
                if(xnou==xfinal&&ynou==yfinal){
                    sol=minim;
                    ok=1;
                    if(ok)
                        break;
                }
                else if(c[xnou][ynou]>=minim){
                    q.push(make_pair(xnou,ynou));
                    viz[xnou][ynou]=1;
                }
            }
        }
    }
    while(!q.empty())
        q.pop();
}
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++){
            c[i][j]=9999999;
            char car;
            cin>>car;
            if(car=='*')
                a[i][j]=0;
            else if(car=='.')
                a[i][j]=++cnt;
            else if(car=='D'){
                dragoni[++cntdrag].first=i;
                a[i][j]=-1;
                dragoni[cntdrag].second=j;
            }
            else if(car=='I'){
                xstart=i,ystart=j;
            }
            else{
                xfinal=i,yfinal=j;
                a[i][j]=++cnt;
            }
        }
    lee(xstart,ystart);
    for(int i=1;i<=cntdrag;i++)
        c[xstart][ystart]=min(c[xstart][ystart],b[dragoni[i].first][dragoni[i].second]-1);
    rmat();
    lee(xfinal,yfinal);
    for(int i=1;i<=cntdrag;i++)
        c[xfinal][yfinal]=min(c[xfinal][yfinal],b[dragoni[i].first][dragoni[i].second]-1);
    rmat();
    int maxi=max(c[xfinal][yfinal],c[xstart][ystart]);
    int st=1,dr=maxi;
    while(st<=dr){
        ok=0;
        minim=(st+dr)/2;
        //cout<<minim<<"\n";
        lee2();
        rmat2();
        if(ok)
            st=minim+1;
        else
            dr=minim-1;
    }
    //cout<<xstart<<ystart<<"\n";
    //cout<<c[xstart][ystart];
    cout<<sol;
}