Cod sursa(job #88796)
Utilizator | 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);
}
}