Cod sursa(job #195486)

Utilizator marinMari n marin Data 18 iunie 2008 21:24:35
Problema Barbar Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.24 kb
#include <stdio.h>
#define DIM 1100
#define INF 2*DIM

int dx[4]={0,0,-1,1};
int dy[4]={1,-1,0,0};

int v[DIM][DIM];
int a[DIM][DIM];
int s[DIM][DIM];
int b[DIM][DIM];
int cd[3][DIM*DIM*2];



int r,c,ok,x1,y1,x2,y2,k,p,u,m,ic,jc,iv,jv;



void caut(int i, int j, int x) {
  v[i][j]=1;
  int k;
  if (ok) return;
  if ((i==x2)&&(j==y2)) {
    ok=1;
    return;
  }
  for (k=0;k<=3;k++) {
    iv = i+dx[k];
    jv = j+dy[k];
    if ((iv<1)||(iv>r)||(jv<1)||(jv>c))
      continue;
    if ((v[iv][jv]==0)&&(b[iv][jv]>=x)) {
      caut(iv,jv,x);
    }
  }
}



int incerc(int x){

  int i,j;
  ok=0;
  for (i=1;i<=r;i++)
    for (j=1;j<=c;j++)
      v[i][j]=0;

  if (b[x1][y1]<x)
    return 0;

  caut(x1,y1,x);

  return ok;

}




int main(){
  FILE *f = fopen("barbar.in","r");
  fscanf(f,"%d %d",&r,&c);
  int i,j;
  for (i=1;i<=r;i++) {
    fscanf(f,"\n");
    for (j=1;j<=c;j++) {
      fscanf(f,"%c",&a[i][j]);

      if (a[i][j]!='*')
	b[i][j]=INF;
      else
	b[i][j]=-1;
      if (a[i][j]=='I') {
	x1=i;y1=j;
      } else if (a[i][j]=='O'){
	x2=i;y2=j;
      }
    }

  }
  fclose(f);




  p=1;
  u=0;
  for (i=1;i<=r;i++)
    for (j=1;j<=c;j++)
      if (a[i][j]=='D') {
	u++;
	cd[1][u]=i;
	cd[2][u]=j;
	b[i][j]=0;
	s[i][j]=u;
      }

  while (p<=u) {
    for (i=0;i<=3;i++) {
      ic=cd[1][p];
      jc=cd[2][p];
      iv=ic+dx[i];
      jv=jc+dy[i];
      if ((a[iv][jv]!='*')&&(iv>=1)&&(iv<=r)&&(jv>=1)&&(jv<=c)&&(b[iv][jv]>b[ic][jc]+1)) {
	if (s[iv][jv]==0) {
	  u++;
	  cd[1][u]=iv;
	  cd[2][u]=jv;
	  s[iv][jv]=u;

	}
	b[iv][jv]=b[ic][jc]+1;
      }
    }
    s[cd[1][p]][cd[2][p]]=0;
    p++;

  }



  FILE *g = fopen("barbar.out","w");
  if (!incerc(0)){
    fprintf(g,"-1");
  } else {
    int max=r+c-2;
    p=0; u=max;
    while (p<=u) {
      m = (p+u)/2;
      if (incerc(m))
	p=m+1;
      else
	u=m-1;
    }

/*    max=p+2;
    if (max>=r+c-2) max=r+c-2;

    int min=p-2;
    if (min<0) min=0;

    for (i=min;i<=max;i++) {

      if (incerc(i) && (!incerc(i+1)))
	break;
    }

    if (i>max) i=max;*/

//    fprintf(g,"%d",i);
    fprintf(g,"%d",u);
  }
//  fprintf(g,"%d",-1);
  fclose(g);




  return 0;
}