Cod sursa(job #1222216)

Utilizator acomAndrei Comaneci acom Data 22 august 2014 17:03:32
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.12 kb
#include<fstream>
#include<queue>
#include<cstring>
using namespace std;
#define INF 0x3f3f3f3f
ifstream fin("barbar.in");
ofstream fout("barbar.out");
struct cel
{
    int l,c;
} x,y;
queue <cel> q;
char A[1005][1005];
int dx[4]={-1,0,1},dy[4]={0,1,0,-1};
int n,m,xi,yi,xo,yo,st,dr,mij,Max,D[1005][1005],N[1005][1005];
void citire()
{
    int i,j;
    fin>>n>>m;
    fin.get();
    for (i=1;i<=n;++i)
    {
        for (j=1;j<=m;++j)
        {
            D[i][j]=INF;
            fin.get(A[i][j]);
            if (A[i][j]=='I') xi=i, yi=j;
            if (A[i][j]=='O') xo=i, yo=j;
            if (A[i][j]=='D')
            {
                D[i][j]=0;
                x.l=i, x.c=j;
                q.push(x);
            }
        }
        fin.get();
    }
    for (i=0;i<=n+1;++i)
        A[i][0]=A[i][m+1]='*';
    for (i=1;i<=m;++i)
        A[0][i]=A[n+1][i]='*';
}
void lee()
{
    int i,lv,cv;
    while (!q.empty())
    {
        x=q.front(); q.pop();
        for (i=0;i<4;++i)
        {
            lv=x.l+dx[i], cv=x.c+dy[i];
            if (A[lv][cv]!='*' && D[lv][cv]>D[x.l][x.c]+1)
            {
                D[lv][cv]=D[x.l][x.c]+1;
                Max=max(Max,D[lv][cv]);
                y.l=lv, y.c=cv;
                q.push(y);
            }
        }
    }
}
int fill(int a)
{
    int i,lv,cv;
    if (D[xi][yi]<a) return 0;
    memset(N,0,sizeof(N));
    N[xi][yi]=1;
    x.l=xi, x.c=yi;
    q.push(x);
    while (!q.empty())
    {
        x=q.front(); q.pop();
        for (i=0;i<4;++i)
        {
            lv=x.l+dx[i], cv=x.c+dy[i];
            if (D[lv][cv]>=a && A[lv][cv]!='*' && !N[lv][cv])
            {
                N[lv][cv]=1;
                y.l=lv, y.c=cv;
                q.push(y);
            }
        }
    }
    return N[xo][yo];
}
int main()
{
    citire();
    lee();
    st=0, dr=Max;
    while (st<=dr)
    {
        mij=(st+dr)>>1;
        if (fill(mij))
            st=mij+1;
        else
            dr=mij-1;
    }
    if (dr>Max || dr<0)
        fout<<"-1\n";
    else
        fout<<dr<<"\n";
    return 0;
}