Cod sursa(job #1128730)

Utilizator RaduGabriel2012Dinu Radu RaduGabriel2012 Data 27 februarie 2014 18:27:55
Problema Barbar Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.06 kb
#include <iostream>
#include <fstream>
#include <queue>
using namespace std;
ifstream f("barbar.in");
ofstream g("barbar.out");
 int n,m,a[1005][1005],dmin[1005][1005],bx,by,fx,fy,sol;
  bool was[1005][1005];
  char s[1005];

  queue <int> l,c;
   int dx[]={0,1,0,-1,0},dy[]={0,0,1,0,-1};

 void Read()
 {  int i,j;
   f>>n>>m;
    f.getline(s,2);
   for(i=1;i<=n;i++)
    { f.getline(s,1003);
       for(j=1;j<=m;j++)
        {
          if (s[j-1]=='*') a[i][j]=1;
          if (s[j-1]=='D') {a[i][j]=2; l.push(i); c.push(j);}
          if (s[j-1]=='I') {a[i][j]=3; bx=i; by=j;}
          if (s[j-1]=='O') {a[i][j]=4; fx=i; fy=j;}
        }
    }
 }

 void CalcMin()
 {  int x,y,i,nx,ny;
    while(!l.empty())
    { x=l.front(); l.pop();
      y=c.front(); c.pop();
       for(i=1;i<=4;i++)
        { nx=x+dx[i];
          ny=y+dy[i];
          if (nx>0 && nx<=n && ny>0 && ny<=m && (a[nx][ny]!=1 && a[nx][ny]!=2 && !dmin[nx][ny]))
           { l.push(nx); c.push(ny); dmin[nx][ny]=dmin[x][y]+1; }
        }
    }
 }

 int Okay(int dist)
 { int x,y,i,j,nx,ny;
   if (dmin[bx][by]<dist || dmin[fx][fy]<dist) return 0;

    while(!l.empty()) {l.pop(); c.pop();}

     for(i=1;i<=n;i++)
      for(j=1;j<=m;j++)
       was[i][j]=0;

     l.push(bx); c.push(by);

    while(!l.empty())
    { x=l.front(); l.pop();
      y=c.front(); c.pop();
       for(i=1;i<=4;i++)
        { nx=x+dx[i];
          ny=y+dy[i];
          if (nx>0 && nx<=n && ny>0 && ny<=m && (a[nx][ny]!=1 && a[nx][ny]!=2 && !was[nx][ny])
              && dmin[nx][ny]>=dist)
           { l.push(nx); c.push(ny); was[nx][ny]=1;
             if (nx==fx && ny==fy) return 1;
           }
        }
    }
  return 0;
 }

 void Search()
 { int st=1,dr=min(dmin[bx][by],dmin[fx][fy]),mid;

    while(st<dr)
    { mid=(st+dr)/2;
       if (Okay(mid)) st=mid+1; else dr=mid-1;
    }

    mid=(st+dr)/2;
   if (!Okay(mid)) mid--;
    sol=mid;
 }

int main()
{  int i,j;
  Read();
  CalcMin();
  Search();

   if (!sol) g<<"-1";
    else g<<"\n";

    return 0;
}