Cod sursa(job #2051583)

Utilizator tudoroprisTudor Opris tudoropris Data 29 octombrie 2017 11:54:07
Problema Barbar Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.91 kb
#include <fstream>
#include <vector>
#include <queue>
#include <cstring>

using namespace std;

ifstream in("barbar.in");
ofstream out("barbar.out");

struct coord{
    int x,y;
};

int temn[1005][1005],n,m,dist[1005][1005],rasp;
bool used[1005][1005];
char x;
const int xdir[4]={-1,1,0,0},ydir[4]={0,0,1,-1};

vector <coord> drag;
queue <coord> q;

coord intrare,iesire;

bool inbound(coord k){
    return k.x>0 && k.x<=n && k.y>0 && k.y<=m;
}

bool check(int k){
    //k = distanta minima fata de cel mai apropiat dragon
    //se cunoaste distanta pana la cel mai apropiat dragon in orice moment
    //se da bfs de la paftenie pana la iesirea din temnita
    //pftenie nu poate trece prin obstacole
    //nu poate fi mai aporape decat k de un dragon // nu se poate dist[paftenie.x][paftenie.y]<k
    while(q.size())q.pop();
    memset(used,0,sizeof used);
    q.push(intrare);
    used[intrare.x][intrare.y]=1;
    while(q.size()){
        coord node=q.front();
        q.pop();
        for(int i=0; i<4; ++i){
            coord newcoord;
            newcoord.x=node.x+xdir[i];
            newcoord.y=node.y+ydir[i];
            if(used[newcoord.x][newcoord.y]==0 && inbound(newcoord) && dist[newcoord.x][newcoord.y]>=k){
                used[newcoord.x][newcoord.y]=1;
                q.push(newcoord);
                if(newcoord.x==iesire.x && newcoord.y==iesire.y)
                    return true;
            }
        }
    }
    return false;
}

void bfs(){
    for(int i=0; i<drag.size(); i++){
        q.push(drag[i]);
    }
    while(q.size()){
        coord nod=q.front();
        q.pop();
        for(int i=0; i<4; i++){
            coord newpoz;
            newpoz.x=nod.x+xdir[i];
            newpoz.y=nod.y+ydir[i];
            if(inbound(newpoz) && !used[newpoz.x][newpoz.y]){
                used[newpoz.x][newpoz.y]=1;
                q.push(newpoz);
                dist[newpoz.x][newpoz.y]=dist[nod.x][nod.y]+1;
            }
        }
    }
}


int cautbin(int l, int r){
    int ans=0;
    while(l<=r){
        int m=(l+r)/2;
        if(check(m)){
            l=m+1;
            ans=m;
        }
        else{
            r=m-1;
        }
    }
    return ans;
}

int main(){
    in>>n>>m;
    for(int i=1; i<=n; i++){
        for(int j=1; j<=m; j++){
            in>>x;
            if(x=='*' || x=='D' || x=='O' || x=='I')
                temn[i][j]=1;
            else temn[i][j]=0;
            if(x=='D'){
                coord locatie;
                locatie.x=i;
                locatie.y=j;
                drag.push_back(locatie);
                }
            if(x=='I'){
                intrare.x=i;
                intrare.y=j;
            }
            if(x=='O'){
                iesire.x=i;
                iesire.y=j;
            }
        }
    }
    bfs();
    rasp=cautbin(1,dist[intrare.x][intrare.y]);
    out<<rasp;
}