Cod sursa(job #1838703)

Utilizator BLz0rDospra Cristian BLz0r Data 1 ianuarie 2017 16:54:09
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.98 kb
#include <fstream>
#include <cstring>
#include <queue>
#include <utility>
using namespace std;

#define NMAX 1002
#define INF 0x3f3f3f3f
#define x first
#define y second

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

queue <pair<int, int>> Q;
pair <int, int> start, finish, aux;

int N, M, cost[NMAX][NMAX];
const int d[4][2] = { {-1,0}, {0,1}, {1,0}, {0,-1} }; // matrice de directii

// functie ce verifica daca o casuta e in interiorul matricei
bool inside(int x, int y) {
    if (x > 0 && y > 0 && x <= N && y <= M)
        return true;
    return false;
}

// Lee clasic
void BFS() {

    while (!Q.empty()) {

        aux = Q.front();
        Q.pop();

        for (int i = 0; i < 4; ++i) {

            int xx = aux.x + d[i][0];
            int yy = aux.y + d[i][1];

            if (inside(xx, yy) && cost[xx][yy] > cost[aux.x][aux.y] + 1) {
                Q.push(make_pair(xx, yy));
                cost[xx][yy] = cost[aux.x][aux.y] + 1;
            }
        }
    }
}

bool viz[NMAX][NMAX];

// functie ce verifica daca exista drum care respecta pasul curent din binara
bool isRoad(int k) {

    Q.push(start);

    memset(viz, 0, sizeof(viz));

    while (!Q.empty()) {

        aux = Q.front();
        Q.pop();

        for (int i = 0; i < 4; ++i) {

            int xx = aux.x + d[i][0];
            int yy = aux.y + d[i][1];

            if (!viz[xx][yy] && inside(xx, yy) && cost[xx][yy] >= k) {
                Q.push(make_pair(xx, yy));
                viz[xx][yy] = 1;
            }
        }
    }

    return viz[finish.x][finish.y];
}

int Bsearch(int st, int dr) {

    int sol = -1;

    while (st <= dr) {

        int mid = (st + dr) >> 1;

        if (isRoad(mid)) {
            sol = mid;
            st = mid + 1;
        }
        else
            dr = mid - 1;
    }

    return sol;
}

int main() {

    char c;

    fin >> N >> M;

    // creez matricea
    for (int i = 1; i <= N; ++i) {
        for (int j = 1; j <= M; ++j) {

            fin >> c;
            switch (c) {

                case '.':
                    cost[i][j] = INF;
                    break;

                case '*':
                    cost[i][j] = -1;
                    break;

                case 'D':
                    cost[i][j] = 0;
                    Q.push( make_pair(i, j));
                    break;

                case 'I':
                    cost[i][j] = INF;
                    start.x = i;
                    start.y = j;
                    break;

                case 'O':
                    cost[i][j] = INF;
                    finish.x = i;
                    finish.y = j;
                    break;
            }
        }
    }

    BFS(); //precalculam distantele de la sursa

    // cautam binar distanta minima pentru maxime
    int st = 1, dr = min(cost[start.x][start.y], cost[finish.x][finish.y]);
    fout << Bsearch(st, dr);

    return 0;
}