Cod sursa(job #350161)

Utilizator AndreiDDiaconeasa Andrei AndreiD Data 22 septembrie 2009 21:36:31
Problema Barbar Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.48 kb
#include <cstdio>   
  
#define Nmax 1010   
  
#define file_in "barbar.in"   
#define file_out "barbar.out"   
  
#define Inf 0x3f3f3f3f   
  
int dx[]={-1,0,+1,0};   
int dy[]={0,+1,0,-1};   
  
int x[Nmax*Nmax];   
int y[Nmax*Nmax];   
int r,c;   
int ri,rf,ci,cf;   
char a[Nmax][Nmax];   
int l[Nmax][Nmax];   
char s[Nmax];   
  
void dragon(int dist)   
{   
    int i,j,k,lne,cne,xc,yc,ls,ld;   
    ld=0;   
    for (i=1;i<=r;++i)   
         for (j=1;j<=c;++j)   
         {   
             l[i][j]=Inf;   
             //afla coordonatele dragonilor   
             if (a[i][j]=='D')   
             {   
                 x[ld]=i;   
                 y[ld++]=j;   
                 l[i][j]=0;   
             }   
         }   
       
  
    ls=0;   
       
    while(ls<ld)   
    {   
        xc=x[ls];   
        yc=y[ls];   
           
        if (l[xc][yc]<dist)   
        {   
        for (k=0;k<4;++k)   
        {   
            lne=xc+dx[k];   
            cne=yc+dy[k];   
               
            if (lne<1 || lne>r || cne<1 || cne>c)   
                continue;    
            if (a[lne][cne]=='*')
			     continue;
			if (l[lne][cne]>l[xc][yc]+1)   
            {   
                l[lne][cne]=l[xc][yc]+1;   
                //ld++;   
                x[ld]=lne;   
                y[ld++]=cne;   
                //ld++;   
            }   
        }   
        }   
        ls++;   
    }   
       
    for (i=1;i<=r;++i)   
         for (j=1;j<=c;++j)   
              if (a[i][j]=='*' || l[i][j]<dist)   
                  l[i][j]=0;   
                  else  
                  l[i][j]=1;   
}   
  
bool ok()   
{   
    int xc,yc,lne,cne,i,j,k,ls,ld;   
    if (l[ri][ci]==0) return false;   
    l[ri][ci]=2;   
    ls=0;   
    ld=1;   
    x[0]=ri;   
    y[0]=ci;   
       
    while(ls<ld)   
    {   
        xc=x[ls];   
        yc=y[ls];   
           
        if (l[xc][yc]==2)   
        {   
        for (k=0;k<4;++k)   
        {   
            lne=xc+dx[k];   
            cne=yc+dy[k];   
            if (lne<1 || lne>r || cne<1 || cne>c)   
                continue;    
            if (l[lne][cne]!=1)
                continue;				
            //ld++;   
            x[ld]=lne;   
            y[ld++]=cne;   
            //ld++;   
            l[lne][cne]=2;   
        }   
        }   
        ls++;   
    }   
  
    if (l[rf][cf]==2)   
        return true;   
    else  
        return false;   
}   
           
  
  
void citire()   
{   
    int i,j;   
    freopen(file_in,"r",stdin);   
           
    scanf("%d %d", &r,&c);   
    
		for (i=1;i<=r;++i)
		     for (j=1;j<=c;++j)
		     {
			 scanf(" %c", &a[i][j]);

			 if (a[i][j] == 'I')
				ri=i, ci=j;
			else
			if (a[i][j]=='O')
				rf=i,cf=j;
		    }
}   
  
void solve()   
{   
    int p,u,rez,mij;   
    //binary search   
    rez=-1;   
    p=0;   
    u=1001001;   
    while(p<=u)   
    {   
        mij=(p+u)>>1;   
        dragon(mij);   
        if (ok())   
        {   
            rez=mij;   
            p=mij+1;   
        }   
        else  
            u=mij-1;   
	}   
    freopen(file_out,"w",stdout);          
    printf("%d", rez);   
       
}   
  
  
int main()   
{   
    citire(); 
    solve();   
    //printf("%d %d %d %d", ri,ci,rf,cf);   
       
    fclose(stdin);   
    fclose(stdout);   
       
    return 0;   
}