Cod sursa(job #185675)

Utilizator toni2007Pripoae Teodor Anton toni2007 Data 25 aprilie 2008 19:35:12
Problema Barbar Scor 90
Compilator c Status done
Runda Arhiva de probleme Marime 3.02 kb
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#define N 1010
//#define MAX 1051000
#define INF 1<<20
const int dx[]={1,0,-1,0};
const int dy[]={0,1,0,-1};
const int MAX=N*N;
struct poz{
	int x,y;
};
int x,y,nr;
int d[N][N];   // distanta pana la cel mai apropiat dragon
int v[N][N];   // costul minim in i si j
char a[N][N];
int max(int a,int b){
    if (a>b)
      return a;
    return b;
}
int min(int a,int b){
    if (a<b)
      return a;
    return b;
}
int vizitat[N][N];
struct poz dragoni[N*N],start,end;
void scan(){
    int i,j;
    freopen("barbar.in","r",stdin);
    freopen("barbar.out","w",stdout);
    scanf("%d%d\n",&x,&y);
    for (i=1;i<=x;++i){
       for (j=1;j<=y+1;++j){
          scanf("%c",&a[i][j]);
          d[i][j]=INF;
          if (a[i][j]=='I')
            start=(struct poz){i,j};
          if (a[i][j]=='O')
            end=(struct poz){i,j};
          if (a[i][j]=='D'){
            dragoni[++nr]=(struct poz){i,j};
            d[i][j]=0;
          }
       	  if (a[i][j]=='*')
            d[i][j]=-1;
      }
      //scanf("\n");
    }
}
void find_dist(){
    int p,u,i;
    struct poz coada[MAX],now,e;
    p=u=1;
    for (i=1;i<=nr;++i)
       coada[u++]=dragoni[i];
    while (p<u){			//   cat timp coada nu e vida
      e=coada[p++];   	//	 scot primul element din coada
      for (i=0;i<4;++i){    //	 parcurg toti vecinii lui e
         now=(struct poz){e.x+dx[i],e.y+dy[i]};
         if (now.x>=1 && now.y>=1 && now.x<=x && now.y<=y ){
         	if (d[now.x][now.y]>d[e.x][e.y]+1){
            	d[now.x][now.y]=d[e.x][e.y]+1;
             	coada[u++]=(struct poz){now.x,now.y};//	adaug now in coada
         	}
         }
      }
    }
}
void copiaza(){
    int i,j;
    for (i=1;i<=x;++i)
       for (j=1;j<=y;++j)
          //v[i][j]=d[i][j];
          v[i][j]=-2;
}
inline void next(int *x){
       if(*x==MAX)
         *x=0;
       else
         ++(*x);
}
void lee(){
    int p,u,i;
    struct poz coada[MAX],e,now;
    p=u=1;
    coada[u++]=start;v[start.x][start.y]=d[start.x][start.y];
    while (p<u){			// cat timp coada nu e vida
      e=coada[p];
      next(&p);// scot primul element din coada
      for (i=0;i<4;++i){	// parcurg vecinii lui i
         now=(struct poz){e.x+dx[i],e.y+dy[i]};
         if (now.x>=1 && now.y>=1 && now.x<=x && now.y<=y){
         	if (min(v[e.x][e.y],d[now.x][now.y])>v[now.x][now.y]){
           		//vizitat[now.x][now.y]=1;
          	 	v[now.x][now.y]=min(d[now.x][now.y],v[e.x][e.y]);
           		coada[u]=now;
                        next(&u);
         	}
         }
      }
    }
}
void print(){
    int i,j;
    /*for (i=1;i<=x;++i){
       for (j=1;j<=y;++j)
          printf("%d ",d[i][j]);
       printf("\n");
    } */
    if (v[end.x][end.y]==-2)
      printf("-1\n");
    else
      printf("%d\n",v[end.x][end.y]);
    fclose(stdin);
    fclose(stdout);
    exit(0);
}
int main(){
    scan();
    find_dist();
    copiaza();
    lee();
    print();
}