Cod sursa(job #195475)

Utilizator marinMari n marin Data 18 iunie 2008 20:47:12
Problema Barbar Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.2 kb
#include <stdio.h>
#define DIM 1021
#define INF 2*DIM

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

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



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,iv,jv;
  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-1;
    p=0; u=max;
    while (p<=u) {
      m = (p+u)/2;
      if (incerc(m))
	p=m+1;
      else
	u=m-1;
    }

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

    for (i=(p-2>=0?p-2:0);i<=max;i++)
      if (incerc(i) && (!incerc(i+1)))
	break;
    if (i>max) i=max;

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




  return 0;
}