Cod sursa(job #64567)

Utilizator sealTudose Vlad seal Data 4 iunie 2007 10:45:07
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.71 kb
#include<stdio.h>
#define Nm 1001
char M[Nm][Nm];
int D[Nm][Nm],U[Nm][Nm],Q[Nm*Nm],n,m,x0,y0;
int Dx[]={-1,0,1,0},Dy[]={0,1,0,-1};

void read()
{
    int i;

    freopen("barbar.in","r",stdin);
    scanf("%d%d",&n,&m);
    for(i=0;i<n;++i)
	scanf("%s",M[i]);
}

void BFS1()
{
    int i,j,x,y,nx,ny,l=0,r=-1;

    for(i=0;i<n;++i)
	for(j=0;j<m;++j)
	    if(M[i][j]=='D')
		Q[++r]=(i<<10)+j;
	    else
	    {
		D[i][j]=n*m;
		if(M[i][j]=='I')
		{
		    x0=i;
		    y0=j;
		}
	    }

    while(l<=r)
    {
	x=Q[l++];
	y=x&1023;
	x>>=10;
	for(i=0;i<4;++i)
	{
	    nx=x+Dx[i];
	    ny=y+Dy[i];
	    if(nx==-1 || nx==n || ny==-1 || ny==m)
	        continue;
	    if(M[nx][ny]!='*' && D[nx][ny]==n*m)
	    {
		D[nx][ny]=D[x][y]+1;
		Q[++r]=(nx<<10)+ny;
	    }
	}
    }
}

int BFS2(int d)
{
    int i,j,x,y,nx,ny,l,r;

    if(D[x0][y0]<d)
	return 0;

    Q[l=r=0]=(x0<<10)+y0;
    for(i=0;i<n;++i)
	for(j=0;j<m;++j)
	    U[i][j]=0;
    U[x0][y0]=1;

    while(l<=r)
    {
	x=Q[l++];
	y=x&1023;
	x>>=10;
	for(i=0;i<4;++i)
	{
	    nx=x+Dx[i];
	    ny=y+Dy[i];
	    if(nx==-1 || nx==n || ny==-1 || ny==m)
		continue;
	    if(M[nx][ny]!='*' && !U[nx][ny] && D[nx][ny]>=d)
	    {
		if(M[nx][ny]!='D' && M[nx][ny]!='.')
		    return 1;
		U[nx][ny]=1;
		Q[++r]=(nx<<10)+ny;
	    }
	}
    }
    return 0;
}

int solve()
{
    int i,j,k;

    BFS1();
    i=0; j=n*m-1;
    while(i<j)
    {
	k=i+j-((i+j)>>1);
	if(BFS2(k))
	    i=k;
	else
	    j=k-1;
    }
    if(BFS2(i))
	return i;
    return -1;
}

void write(int x)
{
    freopen("barbar.out","w",stdout);
    printf("%d\n",x);
}

int main()
{
    read();
    write(solve());
    return 0;
}