Cod sursa(job #3238435)

Utilizator GabrielPopescu21Silitra Gabriel - Ilie GabrielPopescu21 Data 25 iulie 2024 15:31:46
Problema Barbar Scor 90
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.81 kb
#include <iostream>
#include <fstream>
#include <queue>
#include <vector>
#include <climits>

using namespace std;

const int DIRS = 4;
const int dx[DIRS] = {-1, 1, 0, 0};
const int dy[DIRS] = {0, 0, -1, 1};

struct Cell {
    int x, y;
};

bool isValid(int x, int y, int R, int C, const vector<string>& grid) {
    return x >= 0 && x < R && y >= 0 && y < C && grid[x][y] != '*';
}

bool canReach(int minDist, const vector<vector<int>>& dist, Cell start, Cell exit, int R, int C, const vector<string>& grid) {
    queue<Cell> q;
    vector<vector<bool>> visited(R, vector<bool>(C, false));
    q.push(start);
    visited[start.x][start.y] = true;

    while (!q.empty()) {
        Cell current = q.front();
        q.pop();
        if (current.x == exit.x && current.y == exit.y) {
            return true;
        }
        for (int d = 0; d < DIRS; ++d) {
            int nx = current.x + dx[d];
            int ny = current.y + dy[d];
            if (isValid(nx, ny, R, C, grid) && !visited[nx][ny] && dist[nx][ny] >= minDist) {
                visited[nx][ny] = true;
                q.push({nx, ny});
            }
        }
    }
    return false;
}

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

    int R, C;
    fin >> R >> C;
    vector<string> grid(R);
    for (int i = 0; i < R; ++i) {
        fin >> grid[i];
    }

    Cell start, exit;
    queue<Cell> dragons;
    vector<vector<int>> dist(R, vector<int>(C, INT_MAX));
    vector<vector<bool>> visited(R, vector<bool>(C, false));

    for (int i = 0; i < R; ++i) {
        for (int j = 0; j < C; ++j) {
            if (grid[i][j] == 'I') {
                start = {i, j};
            } else if (grid[i][j] == 'O') {
                exit = {i, j};
            } else if (grid[i][j] == 'D') {
                dragons.push({i, j});
                dist[i][j] = 0;
                visited[i][j] = true;
            }
        }
    }

    while (!dragons.empty()) {
        Cell current = dragons.front();
        dragons.pop();
        for (int d = 0; d < DIRS; ++d) {
            int nx = current.x + dx[d];
            int ny = current.y + dy[d];
            if (isValid(nx, ny, R, C, grid) && !visited[nx][ny]) {
                dist[nx][ny] = dist[current.x][current.y] + 1;
                visited[nx][ny] = true;
                dragons.push({nx, ny});
            }
        }
    }

    int left = 0, right = 1e9;
    int bestDist = -1;

    while (left <= right) {
        int mid = (left + right) / 2;
        if (canReach(mid, dist, start, exit, R, C, grid)) {
            bestDist = mid;
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }

    fout << bestDist << endl;

    fin.close();
    fout.close();

    return 0;
}