Cod sursa(job #1330894)

Utilizator vendettaSalajan Razvan vendetta Data 31 ianuarie 2015 02:41:34
Problema Barbar Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.07 kb
#include <bits/stdc++.h>

using namespace std;

const int NMAX = 1004;

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

int aFostVizitat[NMAX][NMAX], distMin[NMAX][NMAX], n, m;
queue<pair<int,int> > q;
pair<int,int> startP, endP;
const int dx[] = {0, -1, 0, 1};
const int dy[] = {-1, 0, 1, 0};

bool eLiber[NMAX][NMAX];

bool inMatrice(int x, int y){
    if (x >= 1 && x <= n && y >= 1 && y <= m) return true;
    return false;
}

void aflaDistanteMinime(){
    while( !q.empty() ){
        int currX = q.front().first;
        int currY = q.front().second;
        q.pop();
        for(int k=0; k<4; ++k){
            int newX = currX + dx[k];
            int newY = currY + dy[k];
            if ( inMatrice(newX, newY) && aFostVizitat[newX][newY] == 0 && eLiber[newX][newY] == true ){
                distMin[newX][newY] = distMin[currX][currY] + 1;
                aFostVizitat[newX][newY] = 1;
                q.push(make_pair(newX, newY));
            }
        }
    }
}

bool pot(int valFixata){
    for(; !q.empty(); q.pop());
    for(int i=1; i<=n; ++i) for(int j=1; j<=m; ++j) aFostVizitat[i][j] = 0;
    aFostVizitat[startP.first][startP.second] = 1;

    q.push(startP);
    while(!q.empty()){
        int currX = q.front().first;
        int currY = q.front().second;
        if (currX == endP.first && currY == endP.second){
            return true;
        }
        q.pop();
        for(int k=0; k<4; ++k){
            int newX = currX + dx[k];
            int newY = currY + dy[k];
            if (inMatrice(newX, newY) && aFostVizitat[newX][newY] == 0 && distMin[newX][newY] >= valFixata && eLiber[newX][newY] == true){
                aFostVizitat[newX][newY] = 1;
                q.push(make_pair(newX, newY));
            }
        }
    }

    return false;
}

void rezolva(){
    aflaDistanteMinime();

    int st = -1;
    int dr = NMAX * NMAX;
    while(dr - st > 1){
        int mij = (st + dr) / 2;
        if (pot(mij)){// vreau cat mai mare
                // am putut => incerc ceva mai mare
            st = mij;
        }else dr = mij;
    }

    g << st << "\n";
}

int main(){
    f >> n >> m;
    f.get();
    string s;
    for(int i=1; i<=n; ++i){
        getline(f, s);
        for(int j=0; j<s.size(); ++j){
            if (s[j] == 'I'){
                // de unde porneste
                startP = make_pair(i, j+1);
                eLiber[i][j+1] = true;
            }else if (s[j] == 'O'){
                // unde trebuie sa ajunga
                endP = make_pair(i, j+1);
                eLiber[i][j+1] = true;
            }else if (s[j] == '*'){
                // perete
                eLiber[i][j+1] = false;
            }else if (s[j] == 'D'){
                // dragon
                eLiber[i][j+1] = false;
                q.push(make_pair(i, j+1));
                aFostVizitat[i][j+1] = 1;
                distMin[i][j+1] = 0;
            }else {
                // liber
                eLiber[i][j+1] = true;
            }
        }
    }

    rezolva();

    return 0;
}