Cod sursa(job #197316)

Utilizator adrianraduleaRadulea Adrian adrianradulea Data 3 iulie 2008 16:05:40
Problema Barbar Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.19 kb
#include<stdio.h>
long mod(long a)
{ if(a<0) a=-a;
  return a;
}
long minim(long a,long b)
{ if(a<b) return a;
  return b;
}
char c;
int xi,yi,xo,yo,x,y,n,m,j,l,a[1002][1002],mt[1002][1002],stx[500000],sty[500000],cx[500000],cy[500000];
long i,k,o;
FILE *f,*g;
int bfs(int x1,int y1)
{ int cx[500000],cy[500000],i,j,ok,stx[500000],sty[500000],k,x,y,o=0;
  k=1; stx[k]=x1; sty[k]=y1;
  while(k)
   { for(i=1;i<=k;i++)
      { x=stx[i]; y=sty[i]; ok=0;
	if(a[x-1][y]!=-1)
	 if(a[x-1][y]!=-3)  { if(a[x][y]+1<a[x-1][y]) { a[x-1][y]=a[x][y]+1; ok=1; }}
	  else { a[x-1][y]=a[x][y]+1; ok=1; }
	if(ok) { o++; cx[o]=x-1; cy[o]=y; } ok=0;
	if(a[x+1][y]!=-1)
	 if(a[x+1][y]!=-3) { if(a[x][y]+1<a[x+1][y]) {a[x+1][y]=a[x][y]+1;ok=1;}}
	  else {a[x+1][y]=a[x][y]+1;ok=1;}
	if(ok) { o++; cx[o]=x+1; cy[o]=y; } ok=0;
	if(a[x][y+1]!=-1)
	 if(a[x][y+1]!=-3) {if(a[x][y]+1<a[x][y+1]) {a[x][y+1]=a[x][y]+1;ok=1;}}
	  else {a[x][y+1]=a[x][y]+1;ok=1;}
	if(ok) { o++; cx[o]=x; cy[o]=y+1; } ok=0;
	if(a[x][y-1]!=-1)
	 if(a[x][y-1]!=-3) {if(a[x][y]+1<a[x][y-1]) {a[x][y-1]=a[x][y]+1;ok=1;}}
	  else {a[x][y-1]=a[x][y]+1;ok=1;}
	if(ok) { o++; cx[o]=x; cy[o]=y-1; } ok=0;
      }
     for(i=1;i<=o;i++) { stx[i]=cx[i]; sty[i]=cy[i]; }
     k=o; o=0;
   }
  return 0;
}
int main()
{ f=fopen("barbar.in","r"); g=fopen("barbar.out","w");
  fscanf(f,"%d%d",&n,&m);
  for(i=1;i<=n;i++)
   { fscanf(f,"%c",&c);
     for(j=1;j<=m;j++)
      { fscanf(f,"%c",&c);
	if(c=='.') { a[i][j]=-3; mt[i][j]=-3; }
	else if(c=='*') a[i][j]=-1;
	else if(c=='D') { a[i][j]=0; mt[i][j]=-3; k++; stx[k]=i; sty[k]=j; }
	else if(c=='I') { a[i][j]=-3; xi=i; yi=j; mt[i][j]=-3; }
	else if(c=='O') { a[i][j]=-3;xo=i; yo=j; mt[i][j]=-3;}
      }
   }

  for(i=1;i<=n;i++) { a[i][0]=-1; a[i][m+1]=-1; }
  for(i=1;i<=m;i++) { a[0][i]=-1; a[n+1][i]=-1; }
  for(i=1;i<=k;i++)
   bfs(stx[i],sty[i]);

  k=1; for(i=1;i<=n;i++) { a[i][0]=2000; a[i][m+1]=2000; mt[i][0]=2000; mt[i][m+1]=2000;}
  for(i=1;i<=m;i++) { a[0][i]=2000; a[n+1][i]=2000; mt[0][i]=2000; mt[n+1][i]=2000;}
  stx[k]=xi; sty[k]=yi; mt[xi][yi]=a[xi][yi];
  while(k)
   { o=0;
     for(i=1;i<=k;i++)
      { x=stx[i]; y=sty[i];
	if(a[x][y+1]!=-1)
	 { if(mt[x][y+1]==-3) { mt[x][y+1]=minim(mt[x][y],a[x][y+1]); o++; cx[o]=x; cy[o]=y+1; }
	   else if(mt[x][y]>mt[x][y+1]&&mt[x][y]<=a[x][y+1]) { mt[x][y+1]=mt[x][y];
	   o++; cx[o]=x; cy[o]=y+1;}
	 }
	if(a[x][y-1]!=-1)
	 { if(mt[x][y-1]==-3) { mt[x][y-1]=minim(mt[x][y],a[x][y-1]);o++; cx[o]=x; cy[o]=y-1; }
	   else if(mt[x][y]>mt[x][y-1]&&mt[x][y]<=a[x][y-1]) { mt[x][y-1]=mt[x][y];
	   o++; cx[o]=x; cy[o]=y-1;}
	 }
	if(a[x+1][y]!=-1)
	 { if(mt[x+1][y]==-3) { mt[x+1][y]=minim(mt[x][y],a[x+1][y]); o++; cx[o]=x+1; cy[o]=y; }
	   else if(mt[x][y]>mt[x+1][y]&&mt[x][y]<=a[x+1][y]) { mt[x+1][y]=mt[x][y];
	   o++; cx[o]=x+1; cy[o]=y;}
	 }
	if(a[x-1][y]!=-1)
	 { if(mt[x-1][y]==-3) { o++; cx[o]=x-1; cy[o]=y; mt[x-1][y]=minim(mt[x][y],a[x-1][y]);}
	   else if(mt[x][y]>mt[x-1][y]&&mt[x][y]<=a[x-1][y]) { mt[x-1][y]=mt[x][y];
	   o++; cx[o]=x-1; cy[o]=y;}
	 }
      }
     for(i=1;i<=o;i++) { stx[i]=cx[i];sty[i]=cy[i]; }
     k=o;
   }
  x=mt[xo][yo]; if(x==-3) x=-1; fprintf(g,"%d",x);
  fclose(g);
  return 0;
}