Cod sursa(job #88796)

Utilizator alzwdedVlad Mesco alzwded Data 3 octombrie 2007 23:43:46
Problema Barbar Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 8.16 kb
#include <stdio.h>
#include <stdlib.h>

/*
        problema: paftenie barbarul s-a pierdut intr-o temnitza, ajuta-l sa iasa
        output: gaseste maximul distantei minime la care trebuie sa se aproprie
            paftenie in drumul sau
            *pote merge doar in sus, jos, stanga, dreapta (aka o celul are 4 vec)
        input: m n
        labirint -  .=gol
                    *=perete
                    D=dragon
                    I=pozitia de plecare
                    D=dragon
                    
        pasi: 1.seteaza "raza dragonilor" - adica umplu pe o raza de x cu flacari de 
                    balaozaur
            2. incearca sa gasesti drum
            3. daca se blocheaza scade raza de foc a dragonilor
            4. daca gasesti drum, parcurge drumu si pe raza d x 
                    vezi la cat e cel mai apropiat dragon
            5. roaga-te sa mearga
*/
#define MAX(A,B) (A>B)?A:B
#define MIN(A,B) (A>B)?B:A
const int kx[4]={0,1,0,-1},ky[4]={1,0,-1,0};
FILE *f,*g;
int **b,m,n,max,flag;
//int **a;
int drumvalid,si,sj;
//char /****/a;
void citire();
void umple_flacari();
int redu();
int lee(int **b);

int main(int arqc, char *argv[])
{
    f=fopen("barbar.in","r");
    g=fopen("barbar.out","w");
    
    citire();
    max=MAX(n,m)-1;
    umple_flacari();
    do{
        flag=redu();
        lee(b);
    }while(flag);
  	
  	fprintf(g,"%d",max);
  	fclose(g);
  	
    return 0;
}

void citire(){
    int i,j;
     
    fscanf(f,"%d %d",&m,&n);

//    a=(char**)malloc(m*n*sizeof(char));
    b=(int**)malloc(m*n*sizeof(int));

    for(i=0;i<n;i++){
        for(j=0;j<n;++j){
            char a=fgetc(f);
            switch(a){
                case '.':{
                    b[i][j]=-1;
                    break;
                }
                case 'D':{
                    b[i][j]=-3;
                    break;
                }
                case 'O':{
                    b[i][j]=-2;
                    break;
                }
                case 'I':{
                    b[i][j]=0;
                    si=i;
                    sj=j;
                    break;
                }
                case '*':{
                    b[i][j]=-3;
                }       
            }
        }
    }
}

void umple_flacari(){
    int i;
    
    for(i=0;i<n;++i){
        int j;
        
        for(j=0;j<n;++j){
            if(b[i][j]==-3){
                /*begin filling on a x mile radius*/
                /*cer scuze dar nu vad cum pot include astea intr-o functie umana*/
                int wj; //var folosita pe post de i/j
                /*for(k=0;k<4;++k){if(i+k<n&&j+k<m&&i+k>=0&&j+k>=0){}}*/
                //k=1
                wj=j;
                while(wj+1<m){
                    if(b[i][++wj]==-1){
                        b[i][wj]=-4; /* -4 e foc de dragon :>*/
                    }
                }
                wj=j;
                while(wj){
                    if(b[i][--wj]==-1){
                        b[i][wj]=-4;
                    }
                }
                wj=i;
                while(wj+1<n){
                    if(b[++wj][j]==-1){
                        b[wj][j]=-4;
                    }
                }
                wj=i;
                while(wj){
                    if(b[--wj][j]==-1){
                        b[wj][j]=-4;
                    }
                }
//end big thing
            }
        }
    }
}

int redu(){
    int i;
    int trv=0;
    
    for(i=0;i<n;++i){
        int j;
        
        for(j=0;j<m;++j){
            if(b[i][j]==-3){
/*begin reducing on a x mile radius*/
                int wj;
                
                wj=j;
                while(b[i][wj]!=-1&&wj<m-1){
                    wj++;
                }
                if(wj==m-1){
                    while(b[i][wj]!=-4&&b[i][wj]!=-3){
                        wj--;
                    }
                    if(b[i][wj]==-4){
                        b[i][wj]=-1;
                        trv=1;
                    }
                }
                
                wj=j;
                while(b[i][wj]!=-1&&wj>0){
                    wj--;
                }
                if(wj==0){
                    while(b[i][wj]!=-4&&b[i][wj]!=-3){
                        wj--;
                    }
                    if(b[i][wj]==-4){
                        b[i][wj]=-1;
                        trv=1;
                    }
                }
                
                wj=i;
                while(b[wj][j]!=-1&&wj<n-1){
                    wj++;
                }
                if(wj=n-1){
                    while(b[wj][j]!=-4&&b[wj][j]!=-3){
                        wj--;
                    }
                    if(b[wj][j]=-4){
                        b[wj][j]=-1;
                        trv=1;
                    }
                }
                
                wj=i;
                while(b[wj][j]!=-1&&wj>0){
                    wj--;
                }
                if(b[wj][j]==0){
                    while(b[wj][j]!=-4&&b[wj][j]!=-3){
                        wj++;
                    }
                    if(b[wj][j]==-4){
                        b[wj][j]=-1;
                        trv=1;
                    }
                }
            }
//end of big thing
        }
    }
    return trv;
}

void drumizeaza(int ii,int jj){
/*aici e aparent cel mai important procedura din programul,
aici (teoretic) se afla maxima distantei minime
*//*
    if(b[i][j]!=-2){
        int k;
    
        //insert search for dragonzlol
    
        for(k=0;k<4;++k){
            if(i+kx[k]<n&&j+ky[k]<m&&i+kx[k]>=0&&j+ky[k]>=0)
                drumizeaza(i+kx[k],j+ky[k]);
        }
    }else{
           
    }*/
    int i,j;
    for(i=0;i<n;++i){
        for(j=0;j<m;++j){
            if(b[i][j]==-3){
                int wj;
//                int george;//george e[ra] distanta de la dragon la paftimie
                
                wj=j;
                while(wj<m-1){
                    wj++;
                    if(b[i][wj]>=0){
                        max=MIN(wj-j+1,max);
                        break;
                    }
                }
                
                wj=j;
                while(wj){
                    wj--;
                    if(b[i][wj]>=0){
                        max=MIN(j-wj+1,max);
                        break;
                    }
                }
                
                wj=i;
                while(wj<n-1){
                    wj++;
                    if(b[wj][j]>=0){
                        max=MIN(i-wj+1,max);
                        break;
                    }
                }
                
                wj=i;
                while(wj){
                    wj--;
                    if(b[wj][j]>=0){
                        max=MIN(i-wj+1,max);
                        break;
                    }
                }
//insert whileuri satanice aici... begin epic quest for road
                
            }
        }/*chiar ar fi trebuit sa tiu minte coordonatele dragonilor sa nu mai caut atata...lol*/
    }
}

int lee(int **b)
{
/*uh boy... this 'll be epic*/
    int i,pas=0,drumvalid=0,miscari;
    
    do{
        int miscari=0;
        for(i=0;i<n;++i){
            int j;
        
            for(j=0;j<m;++j){
                if(b[i][j]==pas){
                    int k;
                    
                    for(k=0;k<4;++k){
                        if(i+kx[k]<n&&j+ky[k]<m&&i+kx[k]>=0&&j+ky[k]>=0){
                            if(b[i+kx[k]][j+ky[k]]==-2){
                                drumvalid=1;
                            }
                            if(b[i+kx[k]][j+ky[k]]==-1){
                                b[i+kx[k]][j+ky[k]]=pas+1;
                                miscari=1;
                            }
                        }
                    }
                }
            }
        }
        pas++;
    }while(miscari);
    
    if(drumvalid){
        //a=b;
        drumizeaza(si,sj);
    }
}