Cod sursa(job #22516)

Utilizator love_for_uSpancioc Riana love_for_u Data 26 februarie 2007 19:31:45
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.42 kb
#include <stdio.h>
#include <string.h>
#define NMAX 2000
typedef struct
	{
	 int x,y;
	} coord;
int n,m;
int xi,yi,xf,yf;
int dx[]={0,-1,0,1,0},dy[]={0,0,1,0,-1};
char s[NMAX+1][NMAX+1];
int d[NMAX+1][NMAX+1];
coord coada[NMAX*NMAX+1];
char viz[NMAX+1][NMAX+1];
int plee(int dist)
{
 int p=0,q=0,i,xx,yy;
 memset(viz,0,sizeof(viz));
 coada[0].x=xi;
 coada[0].y=yi;
 viz[xi][yi]=1;
 while (p<=q)
       {
	xx=coada[p].x;
	yy=coada[p].y;
	for (i=1;i<=4;i++)
	    if (xx+dx[i]>=0 && yy+dy[i]>=0)
	    if (d[xx+dx[i]][yy+dy[i]]>=dist && s[xx+dx[i]][yy+dy[i]]!='*' && !viz[xx+dx[i]][yy+dy[i]])
	       {
		q++;
		coada[q].x=xx+dx[i];
		coada[q].y=yy+dy[i];
		viz[xx+dx[i]][yy+dy[i]]=1;
		if (xx+dx[i]==xf && yy+dy[i]==yf) return 1;
	       }
	p++;
       }
return 0;
}
int posiesit()
{
 int p=0,q=0,i,xx,yy;
 memset(viz,0,sizeof(viz));
 coada[0].x=xi;
 coada[0].y=yi;
 viz[xi][yi]=1;
 while (p<=q)
       {
	xx=coada[p].x;
	yy=coada[p].y;
	for (i=1;i<=4;i++)
	    if (xx+dx[i]>=0 && yy+dy[i]>=0 && xx+dx[i]<n && yy+dy[i]<m)
	    if (s[xx+dx[i]][yy+dy[i]]!='*' && !viz[xx+dx[i]][yy+dy[i]])
	       {
		q++;
		coada[q].x=xx+dx[i];
		coada[q].y=yy+dy[i];
		viz[xx+dx[i]][yy+dy[i]]=1;
		if (xx+dx[i]==xf && yy+dy[i]==yf) return 1;
	       }
	p++;
       }
return 0;
}
int main()
{
 int i,j,q=-1,xx,yy,p;
 freopen("barbar.in","r",stdin);
 freopen("barbar.out","w",stdout);
 scanf("%d %d",&n,&m);
 gets(s[0]);
 for (i=0;i<n;i++)
     gets(s[i]);
 for (i=0;i<=n;i++)
  for (j=0;j<=m;j++) d[i][j]=32000;
 for (i=0;i<=m;i++) d[n][i]=32001;
 for (j=0;j<=n;j++) d[j][m]=32001;
 for (i=0;i<n;i++)
  for (j=0;j<m;j++)
      {
       if (s[i][j]=='I') xi=i, yi=j;
       if (s[i][j]=='D') coada[++q].x=i, coada[q].y=j, d[i][j]=0;
       if (s[i][j]=='O') xf=i, yf=j;
      }
 p=0;
 while (p<=q)
       {
	xx=coada[p].x;
	yy=coada[p].y;
	for (i=1;i<=4;i++)
	    if (xx+dx[i]>=0 && yy+dy[i]>=0)
	    if (d[xx+dx[i]][yy+dy[i]]==32000 && s[xx+dx[i]][yy+dy[i]]!='*')
	       {
		q++;
		coada[q].x=xx+dx[i];
		coada[q].y=yy+dy[i];
		d[xx+dx[i]][yy+dy[i]]=d[xx][yy]+1;
	       }
	p++;
       }
 int dmax=d[xi][yi];
 long step,dist=0;
 for (step=1; step<=dmax ; step<<=1);
 step<<=1;


 if (!posiesit()) printf("-1\n");
 else
 {
 for ( ; step>0; step>>=1)
  if (dist+step<=dmax)
     if (plee(dist+step)) dist+=step;


 printf("%d\n",dist);
 }
fclose(stdin);
fclose(stdout);
return 0;
}