Cod sursa(job #2287303)

Utilizator ValentinSavoiuFMI Savoiu Valentin-Marian ValentinSavoiu Data 21 noiembrie 2018 19:12:32
Problema Barbar Scor 20
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.62 kb
#include <fstream>
#include <queue>
using namespace std;
ifstream f("barbar.in");
ofstream g("barbar.out");
int A[1003][1003], inQ[1003][1003];
int N, M, i ,j, ist, jst, ifin, jfin;
int dx[] = {0, 0, -1, 1}, dy[] = {1, -1, 0, 0};
queue <pair <int, int> > Q;
pair <int, int> pe;


void read (int &N, int &M) {
    f >> N >> M;
    char aux [1003];
    f.get();
    for (i = 1; i <= N; i++) {
        f.getline(aux, 1001);
        for(j = 1; j <= M; j++) {
            char ch = aux[j - 1];
            switch (ch) {
                case '.' :
                    A[i][j] = 0;
                    break;
                case '*' :
                    A[i][j] = -1;
                    break;
                case 'I' :
                    A[i][j] = 0;
                    ist = i;
                    jst = j;
                    break;
                case 'O' :
                    A[i][j] = 0;
                    ifin = i;
                    jfin = j;
                    break;
                case 'D' :
                    A[i][j] = -1;
                    Q.push(make_pair(i, j));
                    break;
            }
        }
    }
    for (i = 0; i <= N; i++)
        A[i][0] = A[i][M + 1] = -1;
    for (j = 0; j <= M; j++)
        A[0][j] = A[N + 1][j] = -1;
}


void bfdragon() {
    while (!Q.empty()) {
        pe = Q.front();
        Q.pop();
        i = pe.first;
        j = pe.second;
        for (int k = 0; k < 4; k++) {
            int ii = i + dx[k];
            int jj = j + dy[k];
            if ( A[ii][jj] == 0 ) {
                Q.push(make_pair(ii, jj));
                if ( A[i][j] == -1 ) A[ii][jj] = 1;
                else A[ii][jj] = A[i][j] + 1;
            }
        }
    }
}

bool BF(int dist) {
    Q.push(make_pair(ist, jst));
    while(!Q.empty()) {
        pe = Q.front();
        i = pe.first;
        j = pe.second;
        Q.pop();
        for (int k = 0; k < 4; k++) {
            int ii = i + dx[k];
            int jj = j + dy[k];
            if (ii == ifin && jj == jfin) return true;
            if (A[ii][jj] >= dist && inQ[ii][jj] != dist) {
                Q.push(make_pair(ii, jj));
                inQ[ii][jj] = dist;
            }
        }
    }
    return false;
}

int binary_search() {
   int left = 1, right = N * M, last_good = 0;
   while (left <= right) {
       int mid = left + (right - left) / 2;
       if (BF(mid)) {
           left = mid + 1;
           last_good = mid;
       }
       else right = mid - 1;
   }
   if (last_good) return last_good;
   else return -1;
}

int main() {

    read(N, M);
    bfdragon();
    int sol = binary_search();
    if (sol) g << sol;
    else g << -1;
    return 0;
}