Cod sursa(job #3266248)

Utilizator RichardChessBibire David-Alexandru RichardChess Data 6 ianuarie 2025 18:57:13
Problema Barbar Scor 80
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.45 kb
#include <fstream>
#include <queue>
#include <vector>
#include <algorithm>

using namespace std;

ifstream f("barbar.in");
ofstream g("barbar.out");

const int MAX = 1001;
const int INF = 1e9;

char mat[MAX][MAX];
int dist[MAX][MAX];
int R, C;
int startX, startY, endX, endY;
int dx[4] = {0, 0, -1, 1};
int dy[4] = {-1, 1, 0, 0};

void calculateDistances() {
    queue<pair<int, int>> q;

    for (int i = 0; i < R; ++i) {
        for (int j = 0; j < C; ++j) {
            if (mat[i][j] == 'D') {
                dist[i][j] = 0;
                q.push({i, j});
            } else {
                dist[i][j] = INF;
            }
        }
    }

    while (!q.empty()) {
        int x = q.front().first;
        int y = q.front().second;
        q.pop();

        for (int k = 0; k < 4; ++k) {
            int nx = x + dx[k];
            int ny = y + dy[k];

            if (nx >= 0 && nx < R && ny >= 0 && ny < C && mat[nx][ny] == '.' && dist[nx][ny] > dist[x][y] + 1) {
                dist[nx][ny] = dist[x][y] + 1;
                q.push({nx, ny});
            }
        }
    }
}

bool isValid(int minDist) {
    queue<pair<int, int>> q;
    vector<vector<bool>> visited(R, vector<bool>(C, false));

    if (dist[startX][startY] < minDist) return false;

    q.push({startX, startY});
    visited[startX][startY] = true;

    while (!q.empty()) {
        int x = q.front().first;
        int y = q.front().second;
        q.pop();

        if (x == endX && y == endY) return true;

        for (int k = 0; k < 4; ++k) {
            int nx = x + dx[k];
            int ny = y + dy[k];

            if (nx >= 0 && nx < R && ny >= 0 && ny < C && !visited[nx][ny] && mat[nx][ny] != '*' && dist[nx][ny] >= minDist) {
                visited[nx][ny] = true;
                q.push({nx, ny});
            }
        }
    }

    return false;
}

int main() {
    f >> R >> C;

    for (int i = 0; i < R; ++i) {
        for (int j = 0; j < C; ++j) {
            f >> mat[i][j];
            if (mat[i][j] == 'I') {
                startX = i;
                startY = j;
            } else if (mat[i][j] == 'O') {
                endX = i;
                endY = j;
            }
        }
    }

    calculateDistances();

    int left = 0, right = R * C, result = -1;
    while (left <= right) {
        int mid = (left + right) / 2;

        if (isValid(mid)) {
            result = mid;
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }

    g << result;

    return 0;
}