Cod sursa(job #8788)

Utilizator t30Rosu Teodor t30 Data 25 ianuarie 2007 16:37:08
Problema Barbar Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.93 kb
#include<stdio.h>
typedef struct nod { long x; nod *d; } nod;
nod *v[1000010];
long r,c,h[1010][1010],ok[1010][1010],si,sj,fi,fj;
long d[1000100],p,q;
void READ()
{
	long i,j;
	char x;
	FILE *f;
	f=fopen("barbar.in","r");
	fscanf(f,"%ld %ld",&r,&c);
	q=0;//fscanf(f,"%c",&x);
	for(i=1;i<=r;i++)
	{  for(j=1;j<=c;j++)
	  {  fscanf(f,"%c",&x);
		  if(x=='.') h[i][j]=1;
		  else if(x=='D'){  h[i][j]=-1; ok[i][j]=1; d[++q]=1001*i+j; }
		  else if(x=='I'){ h[i][j]=1; si=i; sj=j; }
		  else if(x=='O') { h[i][j]=1; fi=i; fj=j; }
		  else { h[i][j]=2; ok[i][j]=-1; }
	  }
	fscanf(f,"%c",&x);
	}
	fclose(f);
}

void BUILD()
{ long x,y,i,j;
  p=1;
  while(p<=q)
  {
	  x=d[p]/1001;
	  y=d[p]%1001;

		 if(x!=1) if(h[x-1][y]%2!=0 && h[x-1][y]>0 ) { ok[x-1][y]=ok[x][y]+1; d[++q]=(x-1)*1001+y; h[x-1][y]*=-1;}
		 if(x<r) if(h[x+1][y]%2!=0 && h[x+1][y]>0) { ok[x+1][y]=ok[x][y]+1; d[++q]=(x+1)*1001+y; h[x+1][y]*=-1;}
		 if(y>1) if(h[x][y-1]%2!=0 && h[x][y-1]>0) { ok[x][y-1]=ok[x][y]+1; d[++q]=x*1001+y-1; h[x][y-1]*=-1;}
		 if(y<c) if(h[x][y+1]%2!=0 && h[x][y+1]>0) { ok[x][y+1]=ok[x][y]+1; d[++q]=x*1001+y+1; h[x][y+1]*=-1;}
		 p++;
  }
  for(i=1;i<=r;i++)
	 for(j=1;j<=c;j++)
		h[i][j]=0;
  h[si][sj]=ok[si][sj];
}

void SOLVE()
{ nod *p,*w;
  long x,y;
  long i,j;
  x=si*1001+sj;
  p=new nod;
  p->x=x;
  p->d=v[ok[si][sj]];
  v[ok[si][sj]]=p;
  for(i=ok[si][sj];i>=1;i--)
  {
	 p=v[i];
	 while(p)
	 {
		x=p->x/1001;
		y=p->x%1001;

		if(x>1)
			if(ok[x-1][y]!=-1 && h[x-1][y]<(ok[x-1][y]<h[x][y]?ok[x-1][y]:h[x][y]))
			{	 h[x-1][y]=(ok[x-1][y]<h[x][y]?ok[x-1][y]:h[x][y]);
				 w=new nod;
				 w->x=p->x-1001;
				 if(h[x-1][y]==h[x][y]) { w->d=p->d; p->d=w; }
				 else {w->d=v[h[x-1][y]]; v[h[x-1][y]]=w; }
			}
		if(x<r)
			if(ok[x+1][y]!=-1 && h[x+1][y]<(ok[x+1][y]<h[x][y]?ok[x+1][y]:h[x][y]))
			{	 h[x+1][y]=(ok[x+1][y]<h[x][y]?ok[x+1][y]:h[x][y]);
				 w=new nod;
				 w->x=p->x+1001;
				 if(h[x+1][y]==h[x][y]) { w->d=p->d; p->d=w; }
				 else {w->d=v[h[x+1][y]]; v[h[x+1][y]]=w; }
			}
		if(y>1)
			if(ok[x][y]!=-1 && h[x][y-1]<(ok[x][y-1]<h[x][y]?ok[x][y-1]:h[x][y]))
			{	 h[x][y-1]=(ok[x][y-1]<h[x][y]?ok[x][y-1]:h[x][y]);
				 w=new nod;
				 w->x=p->x-1;
				 if(h[x][y-1]==h[x][y]) { w->d=p->d; p->d=w; }
				 else {w->d=v[h[x][y-1]]; v[h[x][y-1]]=w; }
			}
		if(y<c)
			if(ok[x][y]!=-1 && h[x][y+1]<(ok[x][y+1]<h[x][y]?ok[x][y+1]:h[x][y]))
			{	 h[x][y+1]=(ok[x][y+1]<h[x][y]?ok[x][y+1]:h[x][y]);
				 w=new nod;
				 w->x=p->x+1;
				 if(h[x][y+1]==h[x][y]) { w->d=p->d; p->d=w; }
				 else {w->d=v[h[x][y+1]]; v[h[x][y+1]]=w; }
			}
	  p=p->d;
	 }
  }

}


void PRINT()
{ long i,j;
  FILE *g;
  g=fopen("barbar.out","w");
  /*for(i=1;i<=r;i++)
  {  for(j=1;j<=c;j++)
     fprintf(g,"\n");
  }*/ 
  if(h[fi][fj]>1) 
  fprintf(g,"%ld\n",h[fi][fj]-1);
  else fprintf(g,"-1");
  fclose(g);
}


int main()
{
READ();
BUILD();
SOLVE();
PRINT();

return 0;
}