Cod sursa(job #829502)

Utilizator geniucosOncescu Costin geniucos Data 5 decembrie 2012 15:50:01
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.52 kb
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
int i,j,k,i1,j1,i2,j2,mij,p,u,maxi,n,m,ap[1004][1004],d[1004][1004];
char a[1004][1004];
const int d1[]={0,0,1,-1};
const int d2[]={1,-1,0,0};
struct str
{
    int x,y;
};
queue < str > cc;
str acr,ret;
int cor(int i,int j)
{
    if(i>=1&&j>=1&&i<=n&&j<=m) return 1;
    return 0;
}
int ok(int celputin)
{
    if(d[i1][j1]<celputin) return 0;
    while(!cc.empty()) cc.pop();
    memset(ap,0,sizeof(ap));
    acr.x=i1;
    acr.y=j1;
    cc.push(acr);
    ap[i1][j1]=1;
    while(!cc.empty())
    {
        acr=cc.front();
        for(k=0;k<4;k++)
            if(cor(acr.x+d1[k],acr.y+d2[k])&&a[acr.x+d1[k]][acr.y+d2[k]]!='*'&&ap[acr.x+d1[k]][acr.y+d2[k]]==0&&d[acr.x+d1[k]][acr.y+d2[k]]>=celputin)
            {
                ret.x=acr.x+d1[k];
                ret.y=acr.y+d2[k];
                ap[acr.x+d1[k]][acr.y+d2[k]]=1;
                if(ret.x==i2&&ret.y==j2) return 1;
                cc.push(ret);
            }
        cc.pop();
    }
    return 0;
}
int main()
{
freopen("barbar.in","r",stdin);
freopen("barbar.out","w",stdout);
scanf("%d",&n);
scanf("%d\n",&m);
for(i=1;i<=n;i++)
    gets(a[i]+1);
for(i=1;i<=n;i++)
    for(j=1;j<=m;j++)
    {
        if(a[i][j]=='I')
        {
            i1=i;
            j1=j;
        }
        if(a[i][j]=='O')
        {
            i2=i;
            j2=j;
        }
        if(a[i][j]=='D')
        {
            acr.x=i;
            acr.y=j;
            ap[i][j]=1;
            d[i][j]=0;
            cc.push(acr);
        }
    }
//////////////////////////////////////////////////////////////////////////////calculez matricea cu drumul minim fata de fiecare dragon
while(!cc.empty())
{
    acr=cc.front();
    for(k=0;k<4;k++)
    if(cor(acr.x+d1[k],acr.y+d2[k])&&a[acr.x+d1[k]][acr.y+d2[k]]!='*'&&ap[acr.x+d1[k]][acr.y+d2[k]]==0)
    {
        ret.x=acr.x+d1[k];
        ret.y=acr.y+d2[k];
        ap[acr.x+d1[k]][acr.y+d2[k]]=1;
        d[acr.x+d1[k]][acr.y+d2[k]]=d[acr.x][acr.y]+1;
        if(d[acr.x+d1[k]][acr.y+d2[k]]>maxi) maxi=d[acr.x+d1[k]][acr.y+d2[k]];
        cc.push(ret);
    }
    cc.pop();
}
////////////////////////////////////////////////////////////////////////////////caut binar
p=0;
u=maxi;
while(p<=u)
{
    mij=(p+u)>>1;
    if(ok(mij)==0) u=mij-1;
    else
    {
        if(ok(mij+1)==0)
        {
            printf("%d\n",mij);
            return 0;
        }
        p=mij+1;
    }
}
printf("-1\n");
return 0;
}