Cod sursa(job #346231)

Utilizator freak93Adrian Budau freak93 Data 7 septembrie 2009 11:53:50
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.5 kb
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>

using namespace std;

const char iname[]="barbar.in";
const char oname[]="barbar.out";
const int maxn=1005;

char a[maxn][maxn];

int dis[maxn][maxn],n,m,i,j,k,x1,y1,x2,y2,maxv;

queue< pair<int,int> > Q;

bool been[maxn][maxn];

int main()
{
    freopen(iname,"r",stdin);
    freopen(oname,"w",stdout);

    scanf("%d%d\n",&n,&m);
    for(i=1;i<=n;++i)
        fgets(a[i]+1,sizeof(a[i]),stdin);
    for(i=1;i<=n;++i)
        for(j=1;j<=m;++j)
            if(a[i][j]=='D')
                dis[i][j]=0,Q.push(make_pair(i,j));
            else
            {
                dis[i][j]=-1;
                if(a[i][j]=='I')
                    x1=i,y1=j;
                if(a[i][j]=='O')
                    x2=i,y2=j;
            }

    pair<int,int> X;
    int x,y;
    while(!Q.empty())
    {
        X=Q.front();
        Q.pop();
        x=X.first;
        y=X.second;
        if(x>1)
            if(a[x-1][y]!='*'&&dis[x-1][y]==-1)
                dis[x-1][y]=dis[x][y]+1,Q.push(make_pair(x-1,y));

        if(x<n)
            if(a[x+1][y]!='*'&&dis[x+1][y]==-1)
                dis[x+1][y]=dis[x][y]+1,Q.push(make_pair(x+1,y));

        if(y>1)
            if(a[x][y-1]!='*'&&dis[x][y-1]==-1)
                dis[x][y-1]=dis[x][y]+1,Q.push(make_pair(x,y-1));

        if(y<m)
            if(a[x][y+1]!='*'&&dis[x][y+1]==-1)
                dis[x][y+1]=dis[x][y]+1,Q.push(make_pair(x,y+1));
    }

    for(i=0;i<=n+1;++i)
        a[i][0]=a[i][m+1]='*';
    for(i=0;i<=m+1;++i)
        a[0][i]=a[n+1][i]='*';

    maxv=dis[x1][y1];

    int step;

    for(step=1;step<=maxv;step<<=1);
    for(k=0;step;step>>=1)
    if(k+step<=maxv){
        memset(been,false,sizeof(been));
        k+=step;
        Q.push(make_pair(x1,y1));
        been[x1][y1]=1;
        while(!Q.empty())
        {
            X=Q.front();
            Q.pop();
            x=X.first;
            y=X.second;

            if(a[x-1][y]!='*'&&been[x-1][y]==false&&dis[x-1][y]>=k)
                been[x-1][y]=true,Q.push(make_pair(x-1,y));
            if(a[x+1][y]!='*'&&been[x+1][y]==false&&dis[x+1][y]>=k)
                been[x+1][y]=true,Q.push(make_pair(x+1,y));
            if(a[x][y-1]!='*'&&been[x][y-1]==false&&dis[x][y-1]>=k)
                been[x][y-1]=true,Q.push(make_pair(x,y-1));
            if(a[x][y+1]!='*'&&been[x][y+1]==false&&dis[x][y+1]>=k)
                been[x][y+1]=true,Q.push(make_pair(x,y+1));
        }

        if(!been[x2][y2])
            k-=step;
    }

    if(k==0)
    {
        memset(been,false,sizeof(been));
        k+=step;
        Q.push(make_pair(x1,y1));
        been[x1][y1]=1;
        while(!Q.empty())
        {
            X=Q.front();
            Q.pop();
            x=X.first;
            y=X.second;

            if(a[x-1][y]!='*'&&been[x-1][y]==false&&dis[x-1][y]>=k)
                been[x-1][y]=true,Q.push(make_pair(x-1,y));
            if(a[x+1][y]!='*'&&been[x+1][y]==false&&dis[x+1][y]>=k)
                been[x+1][y]=true,Q.push(make_pair(x+1,y));
            if(a[x][y-1]!='*'&&been[x][y-1]==false&&dis[x][y-1]>=k)
                been[x][y-1]=true,Q.push(make_pair(x,y-1));
            if(a[x][y+1]!='*'&&been[x][y+1]==false&&dis[x][y+1]>=k)
                been[x][y+1]=true,Q.push(make_pair(x,y+1));
        }

        if(!been[x2][y2])
            k=-1;
    }

    printf("%d\n",k);

    fclose(stdin);
    fclose(stdout);

    return 0;
}