Cod sursa(job #2082350)

Utilizator DruffbaumPopescu Vlad Druffbaum Data 6 decembrie 2017 00:01:53
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.33 kb
#include <cstdio>
#include <cstring>
#include <queue>

#define l first
#define c second
#define NUM_DIR 4
const int MAXN = 1e3;

char mt[MAXN][MAXN];
int delta[NUM_DIR][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}},
    dist[MAXN][MAXN + 1];
bool vis[MAXN][MAXN];
std::queue <std::pair <int, int> > q;
std::pair <int, int> s, d;

bool pos(int n, int m, int k) {
  int l, c;
  memset(vis, 0, sizeof(vis));
  if (dist[s.l][s.c] < k) {
    return 0;
  }
  vis[s.l][s.c] = 1;
  q.push(s);
  while (!q.empty()) {
    l = q.front().l;
    c = q.front().c;
    q.pop();
    for (int i = 0; i < NUM_DIR; ++i) {
      if (!vis[l + delta[i][0]][c + delta[i][1]] && dist[l + delta[i][0]][c + delta[i][1]] >= k &&
          0 <= l + delta[i][0] && l + delta[i][0] < n && 0 <= c + delta[i][1] && c + delta[i][1] < m) {
        vis[l + delta[i][0]][c + delta[i][1]] = 1;
        q.push({l + delta[i][0], c + delta[i][1]});
      }
    }
  }
  return vis[d.l][d.c];
}

int main() {
  int n, m, l, c, max;
  FILE *f = fopen("barbar.in", "r");
  fscanf(f, "%d%d\n", &n, &m);
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < m; ++j) {
      fscanf(f, "%c", &mt[i][j]);
      switch (mt[i][j]) {
      case 'I':
        s = {i, j};
        mt[i][j] = '.';
        break;
      case 'O':
        d = {i, j};
        mt[i][j] = '.';
        break;
      case 'D':
        q.push({i, j});
        dist[i][j] = 1;
        break;
      }
    }
    fscanf(f, "\n");
  }
  fclose(f);
  while (!q.empty()) {
    l = q.front().l;
    c = q.front().c;
    q.pop();
    for (int i = 0; i < NUM_DIR; ++i) {
      if (mt[l + delta[i][0]][c + delta[i][1]] == '.' && !dist[l + delta[i][0]][c + delta[i][1]]) {
        dist[l + delta[i][0]][c + delta[i][1]] = dist[l][c] + 1;
        q.push({l + delta[i][0], c + delta[i][1]});
      }
    }
  }
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < m; ++j) {
      if (dist[i][j]) {
        --dist[i][j];
      } else {
        dist[i][j] = -1;
      }    
      if (mt[i][j] == 'D') {
        dist[i][j] = 0;
      }
    }
  }
  max = 0;
  for (int k = (1 << 20); k > 0; k >>= 1) {
    if (pos(n, m, k + max)) {
      max += k;
    }
  }
  if (!pos(n, m, 0)) {
    max = -1;
  }
  f = fopen("barbar.out", "w");
  fprintf(f, "%d\n", max);
  fclose(f);
  return 0;
}