Cod sursa(job #2634506)

Utilizator popashtefan10Popa Stefan popashtefan10 Data 11 iulie 2020 11:41:21
Problema Barbar Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.59 kb
#include <iostream>
#include <cstdio>
#include <queue>

using namespace std;

const int RMAX = 1000;

struct poz {
  int lin, col;

  poz(int clin = 0, int ccol = 0) {
    lin = clin, col = ccol;
  }
} start, iesire;

int r, c;
int a[RMAX + 5][RMAX + 5], d[RMAX + 5][RMAX + 5];
queue<poz> q;

int viz[RMAX + 5][RMAX + 5];
int dl[4] = {-1, 0, 1, 0};
int dc[4] = {0, 1, 0, -1};

void bordare() {
  for(int i = 0; i <= r + 1; i++)
    a[i][0] = a[i][c + 1] = -1;
  for(int i = 0; i <= c + 1; i++)
    a[0][i] = a[r + 1][i] = -1;
}

void dijkstra() { /// pt a calcula distantele minime de la dragoni la oricare element al grid-ului
  while(!q.empty()) {
    poz crt = q.front();
    q.pop();

    for(int k = 0; k < 4; k++) {
      int nlin = crt.lin + dl[k];
      int ncol = crt.col + dc[k];
      int nd = d[crt.lin][crt.col] + 1;

      if(a[nlin][ncol] > -1 && (d[nlin][ncol] == 0 || nd < d[nlin][ncol])) {
        d[nlin][ncol] = nd;
        q.push(poz(nlin, ncol));
      }
    }
  }
}

bool posibil(int mind) { /// daca e posibil sa se gaseasca un traseu cu distanta minima >= mind
  while(!q.empty())
    q.pop();

  if(d[start.lin][start.col] < mind)
    return false;
  q.push(start);
  viz[start.lin][start.col] = mind;

  while(!q.empty()) {
    poz crt = q.front();
    q.pop();

    for(int k = 0; k < 4; k++) {
      int nlin = crt.lin + dl[k];
      int ncol = crt.col + dc[k];

      if(a[nlin][ncol] == 0 && d[nlin][ncol] >= mind && viz[nlin][ncol] != mind) {
        viz[nlin][ncol] = mind;
        q.push(poz(nlin, ncol));
      }
    }
  }

  return viz[iesire.lin][iesire.col] == mind;
}

int cb() { /// caut binar distanta minima maxima
  int st = 1, dr = r + c, mij, best = -1;

  while(st <= dr) {
    mij = (st + dr) / 2;

    if(posibil(mij)) {
      best = mij;
      st = mij + 1;
    }
    else
      dr = mij - 1;
  }

  return best;
}

int main() {
  freopen("barbar.in", "r", stdin);
  freopen("barbar.out", "w", stdout);
  char ch;

  scanf("%d %d", &r, &c);
  bordare();

  for(int i = 1; i <= r; i++) {
    scanf("%c", &ch);
    for(int j = 1; j <= c; j++) {
      scanf("%c", &ch);
      if(ch == '.')
        a[i][j] = 0;
      else if(ch == '*')
        a[i][j] = -2;
      else if(ch == 'D') {
        a[i][j] = -1;
        q.push(poz(i, j));
      }
      else if(ch == 'I') {
        a[i][j] = 0;
        start = poz(i, j);
      }
      else if(ch == 'O') {
        a[i][j] = 0;
        iesire = poz(i, j);
      }
    }
  }

  dijkstra();

  printf("%d", cb());

  return 0;
}