Cod sursa(job #2492206)

Utilizator MKLOLDragos Ristache MKLOL Data 14 noiembrie 2019 09:44:19
Problema Barbar Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.46 kb
#include <bits/stdc++.h>
 
#define pb push_back
#define mp make_pair
#define fs first
#define sc second
#define rep(i, from, to) for (int i = from; i < (to); ++i)
#define all(x) x.begin(), x.end()
#define sz(x) (int) (x).size()
#define FOR(i, to) for (int i = 0; i < (to); ++i)
 
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef pair<int,int> pii;
typedef pair<double,double> pdd;
typedef vector<ll> vll;
typedef vector<pair<int,int>> vpi;
typedef pair<ll,ll> pll;
typedef vector<string> vs;
#define MOD 1000000007
#define INF 1000000000LL * 100000000LL
#define Nmax 202020
int T;

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

int D[1020][1020];
int B[1020][1020];
string s[2222];
int mmax = 0;
int N,M;
queue<pii> Q;
int xI, yI, xO, yO;
int isB(int x,int y) {
  if(x < 0 || y < 0 || x >= N || y >= M || s[x][y] == '*') return 1;
  return 0;
}

void do_dragons() {
  while(!Q.empty()) {
    pii a = Q.front(); Q.pop();
    //cout << a.fs << " " << a.sc << endl;
    FOR(k, 4) {
      if(isB(a.fs + dx[k], a.sc + dy[k])) continue;
      if(D[a.fs + dx[k]][a.sc + dy[k]] == 0) {
        D[a.fs + dx[k]][a.sc + dy[k]] = D[a.fs][a.sc] + 1;
        Q.push(mp(a.fs + dx[k], a.sc+dy[k]));
      }
    }
  }
}

int isok(int val) {
  Q.push(mp(xI, yI));
  if(D[xI][yI] < val) return 0; // Punctul de start e obstacol
  while(!Q.empty()) {
    pii a = Q.front(); Q.pop();
    FOR(k, 4) {
      if(isB(a.fs + dx[k], a.sc + dy[k])) continue;
      if(D[a.fs + dx[k]][a.sc + dy[k]] < val) continue;
      if(B[a.fs + dx[k]][a.sc + dy[k]] != val) {
        B[a.fs + dx[k]][a.sc + dy[k]] = val;
        Q.push(mp(a.fs + dx[k], a.sc+dy[k]));
      }
    }
  }
  return B[xO][yO] == val;
}

int main() {
  freopen("barbar.in","r",stdin);
  freopen("barbar.out","w",stdout);
  cin >> N >> M;
  FOR(i, N) {
    cin >> s[i];
  }
  FOR(i, N) {
    FOR(j, M) {
      if(s[i][j] == 'D') {
        D[i][j] = 1;
        Q.push(mp(i,j));
        s[i][j] = '*';
      } else if (s[i][j] == 'I') {
        xI = i; yI = j;
      } else if (s[i][j] == 'O') {
        xO = i; yO = j;
      }
    }
  }

  do_dragons();
  int ret = 0;
  int st = 0;
  int dr = 0;
  FOR(i, N) FOR(j, M) dr = max(dr, D[i][j]);
  while(st <= dr) {
    //cout << "WTF" << endl;
    int mij = (st+dr)/2;
    if(isok(mij)) {
      ret = mij;
      st = mij + 1;
    } else {
      dr = mij - 1;
    }
  }
  cout << ret - 1 << endl;
  
}