Cod sursa(job #2634297)

Utilizator popashtefan10Popa Stefan popashtefan10 Data 10 iulie 2020 13:48:38
Problema Barbar Scor 90
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.88 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;

struct elem {
  poz p;
  int mind;

  elem(poz cp = poz(), int cmind = 0) {
    p = cp;
    mind = cmind;
  }
};

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

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

bool inside(int lin, int col) {
  return lin >= 1 && lin <= r && col >= 1 && col <= c;
}

void dijkstra() { /// pt a calcula distantele minime de la dragoni la oricare element al grid-ului
  while(!q.empty()) {
    elem crt = q.front();
    q.pop();
    if(crt.mind != 0 && crt.mind != d[crt.p.lin][crt.p.col])
      continue;

    for(int k = 0; k < 4; k++) {
      int nlin = crt.p.lin + dl[k];
      int ncol = crt.p.col + dc[k];
      if(!inside(nlin, ncol))
        continue;

      int nd = crt.mind + 1;

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

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(elem(start));
  viz[start.lin][start.col] = mind;

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

    for(int k = 0; k < 4; k++) {
      int nlin = crt.p.lin + dl[k];
      int ncol = crt.p.col + dc[k];
      if(!inside(nlin, ncol))
        continue;

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

  return false;
}

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);
  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(elem(poz(i, j), 0));
      }
      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;
}