Cod sursa(job #2970408)

Utilizator zarg169Roxana zarg169 Data 25 ianuarie 2023 04:29:42
Problema Barbar Scor 10
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.74 kb
//https://www.infoarena.ro/problema/barbar

#include <fstream>
#include <queue>

using namespace std;

char prison[1005][1005];
int distances[1005][1005];
queue <pair<int,int>> bfs;
bool bfsVisited[1005][1005];
bool dfsVisited[1005][1005];
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};

void dfs(pair<int,int> sourceNode, int maxDistance, int row, int column) {
    dfsVisited[sourceNode.first][sourceNode.second] = true;
    for (int i = 0; i < 4; ++i) {
        int neighborX, neighborY;
        neighborX = sourceNode.first + dx[i];
        neighborY = sourceNode.second + dy[i];
        if (neighborX < 0 || neighborX > row) continue;
        if (neighborY < 0 || neighborY > column) continue;
        if (prison[neighborX][neighborY] == '*') continue;
        if (dfsVisited[neighborX][neighborY] == false && distances[neighborX][neighborY] - maxDistance > 0) {
            dfsVisited[neighborX][neighborY] = true;
            dfs({neighborX,neighborY}, maxDistance, row, column);
        }
    }
}

int binarySearch(int left, int right, pair<int, int> exitPosition, pair<int,int> sourceNode, int row, int column) {
    int middle = (left + right) / 2;
    if (left != right) {
        for (int i = 0; i < row; ++i) {
            for (int j = 0; j < column; ++j) {
                dfsVisited[i][j] = false;
            }
        }
        dfs(sourceNode, middle, row, column);
        if (dfsVisited[exitPosition.first][exitPosition.second] == true) {
            return binarySearch(middle + 1, right, exitPosition, sourceNode, row, column);
        } else {
            return binarySearch(left, middle, exitPosition, sourceNode, row, column);
        }
    }
    return middle;
}


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

    int row, column;
    pair <int, int> sourceNode;
    pair <int, int> exit;
    int max = 0;
    fin >> row >> column;

    for (int i = 0; i < row; ++i) {
        for (int j = 0; j < column; ++j) {
            fin >> prison[i][j];
            distances[i][j] = 1000005;
            if (prison[i][j] == 'D') {
                distances[i][j] = 0;
                bfs.push({i,j});
                bfsVisited[i][j] = true;
            }
            if (prison[i][j]== 'I') {
                sourceNode.first = i;
                sourceNode.second = j;
            }

            if (prison[i][j]== 'O') {
                exit.first = i;
                exit.second = j;
            }
        }
    }

    while (!bfs.empty()) {
        pair<int,int> currentNode = bfs.front();
        bfs.pop();
        for (int i = 0; i < 4; ++i) {
            int neighborX, neighborY;
            neighborX = currentNode.first + dx[i];
            neighborY = currentNode.second + dy[i];
            if (neighborX < 0 || neighborX >= row) continue;
            if (neighborY < 0 || neighborY >= column) continue;
            if (prison[neighborX][neighborY] == '*') continue;
            if (bfsVisited[neighborX][neighborY]) continue;

            distances[neighborX][neighborY] = distances[currentNode.first][currentNode.second] + 1;

            bfs.push({neighborX, neighborY});
            bfsVisited[neighborX][neighborY] = true;
        }        
    }

    for (int i = 0; i < row; ++i) {
        for (int j = 0; j < column; ++j) {
            if (prison[i][j] != '*') {
                if (max <= distances[i][j]) {
                    max = distances[i][j];
                }
            }
        }
    }

    int ans = binarySearch(1, max, exit, sourceNode, row, column);

    for (int i = 0; i < row; ++i) {
        for (int j = 0; j < column; ++j) {
            dfsVisited[i][j] = false;
        }
    }
    dfs(sourceNode, ans, row, column);
    if (dfsVisited[exit.first][exit.second]) {
        fout << ans;
    } else {
        fout << -1;
    }
}