Cod sursa(job #369378)

Utilizator vladiiIonescu Vlad vladii Data 28 noiembrie 2009 11:55:14
Problema Barbar Scor 70
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.32 kb
#include <iostream>
#include <fstream>
#include <deque>
using namespace std;

int dx[]={-1, 1, 0, 0};
int dy[]={0, 0, -1, 1};
char mat[1003][1003];
int r, c;
int distanta[1001][1001];

void BFSdragon(int startx, int starty) {
    int mini=1000000, i, d=10000, x, p, q, y, dragon=0;
    deque<pair<int, int> > deq;
    int viz[1001][1001];
    for(x=1; x<=r; x++) {
         for(y=1; y<=c; y++) {
              viz[x][y]=0;
         }
    }
    deq.push_back(make_pair(startx, starty));
    viz[startx][starty]=1;
    while(!deq.empty()) {
         p=deq.front().first;
         q=deq.front().second;
         for(i=0; i<4; i++) {
              x=p+dx[i];
              y=q+dy[i];
              if(viz[x][y]==0 && (mat[x][y]=='I' || mat[x][y]=='D' || mat[x][y]=='.' || mat[x][y]=='O')) {
                   viz[x][y]=viz[p][q]+1;
                   if(viz[x][y]-1<distanta[x][y]) {
                        distanta[x][y]=viz[x][y]-1;
                   }
                   if(mat[x][y]=='D') {
                        distanta[x][y]=0;
                   }
                   deq.push_back(make_pair(x, y));
              }
         }
         deq.pop_front();
    }      
}

int BFS(int startx, int starty, int endx, int endy, int dist) {
    //dist = distanta minima pina la dragon ( > )
    deque<pair<int, int> > Q;
    int ok=0, i, j, d, x, y, p, q, mini;
    char viz[1002][1002];
    for(i=1; i<=r+1; i++) {
         for(j=1; j<=c+1; j++) {
              viz[i][j]=0;
         }
    }
    //verificare
    mini=distanta[startx][starty];
    if(mini<dist) { return 0; }
    viz[startx][starty]=1;
    Q.push_back(make_pair(startx, starty));
    while(!Q.empty()) {
         x=Q.front().first;
         y=Q.front().second;
         for(i=0; i<4; i++) {
              ok=0;
              p=x+dx[i];
              q=y+dy[i];
              //mini=BFSdragon(p, q);
              mini=distanta[p][q];
              if(mini<dist) { ok=1; }
              if(ok==0 && viz[p][q]==0 && (mat[p][q]=='I' || mat[p][q]=='D' || mat[p][q]=='.' || mat[p][q]=='O')) {
                   if(p==endx && q==endy) {
                        return 1;
                   }
                   viz[p][q]=1;
                   Q.push_back(make_pair(p, q));   
              }
         }
         Q.pop_front();
    }                
    return 0;
}

/**
int cautabinar(int startx, int starty, int endx, int endy, int st, int dr) {
    int mij, q;
    while(st<=dr) {
        mij=st+(dr-st)/2;
        q=BFS(startx, starty, endx, endy, mij);
        if(q==0) { dr=mij-1; }
        else {
             if(BFS(startx, starty, endx, endy, mij+1)==1) { 
                  st=mij+1; 
             }
             else { return mij; }
        }
    }
    return -1;
}
**/

int main() {
    fstream f1;
    FILE *out=fopen("barbar.out", "w");
    int i, j, k, p, startx, starty, endx, endy;
    int drx[1001], dry[1001], nrd=0;
    //r linii, c coloane
    f1.open("barbar.in", ios::in);
    f1>>r>>c;
    for(i=1; i<=r; i++) {
         for(j=1; j<=c; j++) {
              distanta[i][j]=99999;
         }
    }    
    for(i=0; i<=r; i++) {
         mat[0][i]='X'; mat[c+1][i]='X';
    }
    for(i=0; i<=c; i++) {
         mat[i][0]='X'; mat[i][r+1]='X';
    }
    mat[r+1][c+1]='X';
    for(i=1; i<=r; i++) {
         for(j=1; j<=c; j++) {
              f1>>mat[i][j];
              if(mat[i][j]=='I') { startx=i; starty=j; }
              if(mat[i][j]=='O') { endx=i; endy=j; }
              if(mat[i][j]=='D') {
                   drx[nrd]=i; dry[nrd]=j;
                   nrd++;
                   //BFSdragon(i, j); 
              }
         }
    }
    for(i=0; i<nrd; i++) {
         BFSdragon(drx[i], dry[i]);
    }
    for(i=1; i<=r; i++) {
         for(j=1; j<=r; j++) {
              cout<<distanta[i][j]<<" ";
         }
         cout<<endl;
    }
    //fprintf(out, "%d\n", cautabinar(startx, starty, endx, endy, 0, 1001));
    int bl=0,br=r*c,bm;
    while (br-bl>1)
    {
        bm=(bl+br)>>1;
        if (BFS(startx, starty, endx, endy, bm)) bl=bm;
        else br=bm;
    }
    if (bl) fprintf(out, "%d\n",bl);
    else 
     if(BFS(startx, starty, endx, endy, 0)) { fprintf(out, "0\n"); }
     else { fprintf(out, "-1\n"); }
    f1.close(); fclose(out);
    return 0;
}