Cod sursa(job #2830743)

Utilizator RoberttoPopescu Paullo Robertto Karloss Robertto Data 10 ianuarie 2022 10:56:15
Problema Barbar Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.07 kb
#include <fstream>
#include <vector>
#include <queue>
#include <cstring>

#define NMAX 1002

using namespace std;

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


int dl[4] = {0, 1, 0, -1};

int dc[4] = {1, 0, -1, 0};


int n, m;

int matrice[NMAX][NMAX], drum[NMAX][NMAX];

queue<pair<int, int>> coada;

int linieStart, coloanaStart, linieEnd, coloanaEnd;

int mini;


void initializare() {
    for (int i = 0; i <= n + 1; i++)
        memset(drum[i], 0, sizeof(drum[i]));
}


int cautDrum(int &valoareMaxima) {
    initializare();
    while (!coada.empty())
        coada.pop();

//    drum.clear();

//    drum.resize(n + 2, vector<int>(m + 2, 0));

    coada.push(make_pair(linieStart, coloanaStart));

    drum[linieStart][coloanaStart] = 1;

    int rez = 0;
    while (!coada.empty() && rez == 0) {
        int x = coada.front().first;
        int y = coada.front().second;
        coada.pop();
        for (int i = 0; i < 4; i++)
            if (drum[x + dl[i]][y + dc[i]] == 0 && (matrice[x + dl[i]][y + dc[i]] - 1) >= valoareMaxima) {

                drum[x + dl[i]][y + dc[i]] = 1;

                if (x + dl[i] == linieEnd && y + dc[i] == coloanaEnd)

                    rez = 1;

                coada.push(make_pair(x + dl[i], y + dc[i]));
            }

    }

    return rez;

}


int cautareBinara(int start, int stop) {

    int pivot;

    while (stop - start > 1) {

        pivot = (start + stop) >> 1;

        if (cautDrum(pivot) == 1)

            start = pivot;

        else

            stop = pivot;

    }

    if (start == 0)

        return -1;

    else

        return start;

}


void lee() {

    while (!coada.empty()) {

        int x = coada.front().first;

        int y = coada.front().second;

        coada.pop();

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

            if (matrice[x + dl[i]][y + dc[i]] == 0) {

                matrice[x + dl[i]][y + dc[i]] = 1 + matrice[x][y];

                coada.push(make_pair(x + dl[i], y + dc[i]));

            }

    }

}


void bordare() {

    for (int i = 0; i <= n + 1; i++)

        matrice[i][0] = matrice[i][m + 1] = -1;

    for (int i = 0; i <= m + 1; i++)

        matrice[0][i] = matrice[n + 1][i] = -1;

}


int main() {

    fin >> n >> m;

//    matrice.resize(n + 2, vector<int>(m + 2, 0));

    for (int i = 1; i <= n; i++) {

        for (int j = 1; j <= m; j++) {

            char caracter;

            fin >> caracter;

            if (caracter == '*')

                matrice[i][j] = -1;

            else if (caracter == 'D') {

                coada.push(make_pair(i, j));

                matrice[i][j] = 1;

            } else if (caracter == 'I') {

                linieStart = i;

                coloanaStart = j;

            } else if (caracter == 'O') {

                linieEnd = i;

                coloanaEnd = j;

            }

        }

    }

    bordare();

    lee();

    if (matrice[linieStart][coloanaStart] <= matrice[linieEnd][coloanaEnd])

        mini = matrice[linieStart][coloanaStart];

    else

        mini = matrice[linieEnd][coloanaEnd];


    fout << cautareBinara(0, mini);

    return 0;

}