Cod sursa(job #2812914)

Utilizator AndreiP15Andrei Enea AndreiP15 Data 5 decembrie 2021 14:23:21
Problema Barbar Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.75 kb
#include <fstream>
#include <queue>
using namespace std;
ifstream cin("barbar.in");
ofstream cout("barbar.out");
int n,m,dist[1005][1005];
bool viz[1005][1005];
char v[1005][1005];
struct celula
{
      int lin,col;
};
queue <celula> q;
celula st,fin;
bool valid1(celula cell)
{
      return(cell.lin>=1&&cell.lin<=n&&cell.col>=1&&cell.col<=m&&v[cell.lin][cell.col]!='*'&&dist[cell.lin][cell.col]==-1);
}
bool valid2(celula cell,int d)
{
      return(cell.lin>=1&&cell.lin<=n&&cell.col>=1&&cell.col<=m&&v[cell.lin][cell.col]!='*'&&!viz[cell.lin][cell.col]&&dist[cell.lin][cell.col]>=d);
}
void lee()
{
      const int dx[]={0, 0,1,-1};
      const int dy[]={1,-1,0, 0};
      while(!q.empty())
      {
            celula cell=q.front();
            q.pop();
            for(int dir=0;dir<4;dir++)
            {
                  celula vc={cell.lin+dx[dir],cell.col+dy[dir]};
                  if(valid1(vc))
                  {
                        dist[vc.lin][vc.col]=dist[cell.lin][cell.col]+1;
                        q.push(vc);
                  }
            }
      }
}
bool ok(int d)
{
      const int dx[]={0, 0,1,-1};
      const int dy[]={1,-1,0, 0};
      if(dist[st.lin][st.col]<d)return false;
      while(!q.empty())q.pop();
      q.push(st);
      for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                  viz[i][j]=false;
      viz[st.lin][st.col]=true;
      while(!q.empty())
      {
            celula cell=q.front();
            q.pop();
            if(cell.lin==fin.lin&&cell.col==fin.col)return true;
            for(int dir=0;dir<4;dir++)
            {
                  celula vc={cell.lin+dx[dir],cell.col+dy[dir]};
                  if(valid2(vc,d))
                  {
                        viz[vc.lin][vc.col]=true;
                        q.push(vc);
                  }
            }
      }
      return false;
}
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
          cin>>(v[i]+1);
          for(int j=1;j<=m;j++)
          {
                dist[i][j]=-1;
                if(v[i][j]=='I')
                {
                      st.lin=i;
                      st.col=j;
                }
                else if(v[i][j]=='D')
                {
                      dist[i][j]=0;
                      q.push({i,j});
                }
                else if(v[i][j]=='O')
                {
                      fin.lin=i;
                      fin.col=j;
                }
          }
    }
    lee();
    int s=1,d=n*m,sol=-1;
    while(s<=d)
    {
          int mij=(s+d)/2;
          if(ok(mij))
          {
                sol=mij;
                s=mij+1;
          }
          else d=mij-1;
    }
    cout<<sol;
    return 0;
}