Cod sursa(job #319267)

Utilizator AndreiDDiaconeasa Andrei AndreiD Data 30 mai 2009 23:41:40
Problema Barbar Scor 70
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.49 kb
#include <cstdio>

#define Nmax 1120

#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 (a[lne][cne]=='*' || lne<1 || lne>r || cne<1 || cne>c)
				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 (l[lne][cne]!=1 || lne<1 || lne>r || cne<1 || cne>c)
				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);
	freopen(file_out,"w",stdout);
	
	scanf("%d %d", &r,&c);
	for (i=1;i<=r;++i)
	{
		gets(s);
		for (j=0;j<c;++j)
			  {
				  a[i][j+1]=s[j];
				  //scanf("% c", &a[i][j]);
				  //afla coordonatele punctului de plecare
				  if (a[i][j+1]=='I')
				  {
					  ri=i;
					  ci=j+1;
				  }
				  //afla coordonatele punctului de iesire
				  if (a[i][j+1]=='O')
				  {
					  rf=i;
					  cf=j+1;
				  }
		      }
	}
}

void solve()
{
	int p,u,rez,mij;
	//binary search
	rez=-1;
	p=0;
	u=1002010;
	while(p<=u)
	{
		mij=(p+u)>>1;
		dragon(mij);
		if (ok())
		{
			rez=mij;
			p=mij+1;
		}
		else
			u=mij-1;
	}
		
	printf("%d", rez);
	
}


int main()
{
	citire();
	solve();
	//printf("%d %d %d %d", ri,ci,rf,cf);
	
	fclose(stdin);
	fclose(stdout);
	
	return 0;
}