Cod sursa(job #377025)

Utilizator pandaemonAndrei Popescu pandaemon Data 23 decembrie 2009 08:00:13
Problema Barbar Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.79 kb
#include<stdio.h>
#include<iostream.h>

#define MAX 1003
#define MINIM(a,b) (a<b ? a:b)

int n,m,i,j;
int mat[MAX][MAX],sol[MAX][MAX];  int st=1,dr=0,pl,pc;   // pointerele cozii "coada"

struct lc {int lin,col;} start,finish,coada[7*MAX*MAX];

int inline init()
{
      scanf("%d %d",&n,&m);   char x;

      for(i=1; i<=n; i++) {  scanf("%c",&x);
      for(j=1; j<=m; j++)
      {  scanf("%c",&x); mat[i][j]=sol[i][j]=-2; /// -2 e spatiu liber, -1 e perete
	 if(x=='D') { coada[++dr].lin=i; coada[dr].col=j; mat[i][j]=0; }
	 if(x=='*') sol[i][j]=mat[i][j]=-1;
	 if(x=='I') { start.lin=i; start.col=j; }   //// start - pozitia de inceput a eroului
	 if(x=='O') { finish.lin=i; finish.col=j; } //// finish - iesirea din templu
      }  }

      //bordare aka "pereti smecheri virtuali"

      for(i=1; i<=n; i++) { mat[0][i]=-1; mat[i][0]=-1; mat[n+1][i]=-1; mat[i][n+1]=-1; }

}


int main()
{
      freopen("barbar.in","r",stdin);
      freopen("barbar.out","w",stdout);

      init();

      while(st<=dr)
      {

      pl=coada[st].lin; pc=coada[st].col;

      if(mat[pl+1][pc]==-2)
      { mat[pl+1][pc]=mat[pl][pc]+1; coada[++dr].lin=pl+1; coada[dr].col=pc;}
      if(mat[pl-1][pc]==-2)
      { mat[pl-1][pc]=mat[pl][pc]+1; coada[++dr].lin=pl-1; coada[dr].col=pc;}
      if(mat[pl][pc+1]==-2)
      { mat[pl][pc+1]=mat[pl][pc]+1; coada[++dr].lin=pl; coada[dr].col=pc+1;}
      if(mat[pl][pc-1]==-2)
      { mat[pl][pc-1]=mat[pl][pc]+1; coada[++dr].lin=pl; coada[dr].col=pc-1;}

      st++;

      }

      /// finalizare

      st=dr=1;  coada[1].lin=start.lin; coada[1].col=start.col;

      sol[start.lin][start.col]= mat[start.lin][start.col];

      while(st<=dr)
      {
      if(st>=200000)
	{ int k,cnt; for(k=st,cnt=0;k<=dr;k++)
	   {coada[++cnt].lin=coada[k].lin; coada[cnt].col=coada[k].col; } st=1; dr=cnt; }

      pl=coada[st].lin; pc=coada[st].col;

      if(sol[pl+1][pc]==-2 || sol[pl+1][pc]< MINIM(sol[pl][pc],mat[pl+1][pc]) )
      { sol[pl+1][pc]=MINIM(sol[pl][pc],mat[pl+1][pc]);
	coada[++dr].lin=pl+1; coada[dr].col=pc;}

      if(sol[pl-1][pc]==-2 || sol[pl-1][pc]< MINIM(sol[pl][pc],mat[pl-1][pc]) )
      { sol[pl-1][pc]=MINIM(sol[pl][pc],mat[pl-1][pc]);
	coada[++dr].lin=pl-1; coada[dr].col=pc;}

      if(sol[pl][pc+1]==-2 || sol[pl][pc+1]< MINIM(sol[pl][pc],mat[pl][pc+1]) )
      { sol[pl][pc+1]=MINIM(sol[pl][pc],mat[pl][pc+1]);
	coada[++dr].lin=pl; coada[dr].col=pc+1;}

      if(sol[pl][pc-1]==-2 || sol[pl][pc-1]< MINIM(sol[pl][pc],mat[pl][pc-1]) )
      { sol[pl][pc-1]=MINIM(sol[pl][pc],mat[pl][pc-1]);
	coada[++dr].lin=pl; coada[dr].col=pc-1;}

      st++; 

      }            


      if(sol[finish.lin][finish.col]==-2) printf("-1\n");
      else printf("%d\n",sol[finish.lin][finish.col]);

printf("\n"); return 0;
}