Cod sursa(job #3352787)

Utilizator mihai.25Calin Mihai mihai.25 Data 1 mai 2026 14:51:12
Problema Barbar Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.91 kb
#include <fstream>

#include <vector>

#include <queue>

using namespace std;

int n, m;

vector<vector<char>> mat;

pair<int, int> startPos, endPos;

vector<vector<int>> dist;

vector<int> dx = {-1, 0, 1, 0}, dy = {0, 1, 0, -1};

bool in_mat(int i, int j) {

    return i >= 1 && i <= n && j >= 1 && j <= m;
}

// calculam pentru fiecare celula distanta pana la cel mai apropiat dragon

void dragonsDistances() {

    dist.resize(n + 1, vector<int>(m + 1, -1));

    queue<pair<int, int>> q;

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

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

            if (mat[i][j] == 'D') {

                dist[i][j] = 0;

                q.push({i, j});
            }
        }
    }

    while (!q.empty()) {

        int x = q.front().first;

        int y = q.front().second;

        q.pop();

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

            int next_x = x + dx[i];

            int next_y = y + dy[i];

            if (in_mat(next_x, next_y) && mat[next_x][next_y] != '*' && dist[next_x][next_y] == -1) {

                dist[next_x][next_y] = dist[x][y] + 1;

                q.push({next_x, next_y});
            }
        }
    }
}

// verificam daca exista un drum de la 'I' la 'O' in care cel mai apropiat dragon sa fie la distanta k

bool canReach(int k) {

    if (dist[startPos.first][startPos.second] < k || dist[endPos.first][endPos.second] < k)
        return false;
    
    vector<vector<bool>> visited(n + 1, vector<bool>(m + 1));

    queue<pair<int, int>> q;

    q.push(startPos);

    while (!q.empty()) {

        if (q.front() == endPos)
            return true;
        
        int x = q.front().first;

        int y = q.front().second;

        q.pop();

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

            int next_x = x + dx[i];

            int next_y = y + dy[i];

            if (in_mat(next_x, next_y) && !visited[next_x][next_y] && mat[next_x][next_y] != '*' && dist[next_x][next_y] >= k) {

                visited[next_x][next_y] = true;

                q.push({next_x, next_y});
            }
        }
    }

    return false;
}

int main() {

    ifstream fin("barbar.in");

    ofstream fout("barbar.out");

    fin >> n >> m;

    mat.resize(n + 1, vector<char>(m + 1));

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

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

            fin >> mat[i][j];

            if (mat[i][j] == 'I')
                startPos = {i, j};
            
            if (mat[i][j] == 'O')
                endPos = {i, j};
        }
    }

    dragonsDistances();

    int ans = -1, left = 0, right = n + m;

    while (left <= right) {

        int mid = left + (right - left) / 2;

        if (!canReach(mid))
            right = mid - 1;
        else {

            ans = mid;

            left = mid + 1;
        }
    }

    fout << ans;

    return 0;
}