Cod sursa(job #3238514)

Utilizator chiriacandrei25Chiriac Andrei chiriacandrei25 Data 26 iulie 2024 13:06:46
Problema Barbar Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.35 kb
#include <fstream>
#include <vector>
#include <queue>

using namespace std;

const int Nmax = 1005;

char a[Nmax][Nmax];
int n, m;
int minDist[Nmax][Nmax];
bool visited[Nmax][Nmax];

struct Cell {
  int x, y;
};
vector<Cell> dragons;
Cell start, finish;
const int dx[] = {-1, 0, 1,  0};
const int dy[] = { 0, 1, 0, -1};

bool isValidCell(Cell cell) {
  return cell.x >= 1 && cell.x <= n && cell.y >= 1 && cell.y <= m &&
    a[cell.x][cell.y] != '*';
}

void leeFromDragons() {
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      minDist[i][j] = -1;
    }
  }
  queue<Cell> q;
  for (Cell dragon : dragons) {
    minDist[dragon.x][dragon.y] = 0;
    q.push(dragon);
  }
  while (!q.empty()) {
    Cell cell = q.front();
    q.pop();
    for (int dir = 0; dir < 4; dir++) {
      Cell neighbor = {cell.x + dx[dir], cell.y + dy[dir]};
      if (!isValidCell(neighbor) || minDist[neighbor.x][neighbor.y] != -1) {
        continue;
      }
      minDist[neighbor.x][neighbor.y] = minDist[cell.x][cell.y] + 1;
      q.push(neighbor);
    }
  }
}

void fill(Cell cell, int dist) {
  visited[cell.x][cell.y] = true;
  for (int dir = 0; dir < 4; dir++) {
    Cell neighbor = {cell.x + dx[dir], cell.y + dy[dir]};
    if (isValidCell(neighbor) && minDist[neighbor.x][neighbor.y] >= dist &&
     !visited[neighbor.x][neighbor.y]) {
      fill(neighbor, dist);
    }
  }
}

bool isValidDistance(int dist) {
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      visited[i][j] = false;
    }
  }
  fill(start, dist);
  return visited[finish.x][finish.y];
}

int findSolution() {
  int left = 1, right = n + m, sol = -1;
  while (left <= right) {
    int mid = (left + right) / 2;
    if (isValidDistance(mid)) {
      sol = mid;
      left = mid + 1;
    } else {
      right = mid - 1;
    }
  }
  return sol;
}

int main() {
  ifstream fin("barbar.in");
  ofstream fout("barbar.out");
  fin >> n >> m;
  for (int i = 1; i <= n; i++) {
    fin >> (char*) (a[i] + 1);
    for (int j = 1; j <= m; j++) {
      if (a[i][j] == 'D') {
        dragons.push_back({i, j});
      } else if (a[i][j] == 'I') {
        start = {i, j};
      } else if (a[i][j] == 'O') {
        finish = {i, j};
      }
    }
  }
  leeFromDragons();
  fout << findSolution() << "\n";
  return 0;
}