Cod sursa(job #3242556)

Utilizator Turcanu_DavidTurcanu David Turcanu_David Data 12 septembrie 2024 16:39:59
Problema Barbar Scor 80
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.37 kb
#include <bits/stdc++.h>

using namespace std;

const int nmax = 1e3 + 2;

int mat[nmax][nmax], dp[nmax][nmax];

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

int f[nmax][nmax];

int n, m, si, sj, ei, ej, cnt;

bool check(int a, int b) {
  if(min(a, b) > 0 && a <= n && b <= m) {
    return 1;
  }
  return 0;
}

void bk(int i, int j, int nr) {
  f[i][j] = cnt;
  for(int d = 0; d < 4; d++) {
    int x = dx[d] + i;
    int y = dy[d] + j;
    if(!check(x, y) || mat[x][y] == 1 || dp[x][y] < nr || f[x][y] == cnt) {
      continue;
    }
    bk(x, y, nr);
  }
}

bool check(int mid) {
  cnt++;
  bk(si, sj, mid);
  if(f[ei][ej] == cnt) {
    return 1;
  }
  return 0;
}

int main(){
  ifstream cin("barbar.in");
  ofstream cout("barbar.out");
  cin >> n >> m;
  for(int i = 0; i < n + 2; i++) {
    for(int j = 0; j < m + 2; j++) {
      dp[i][j] = 1e9;
    }
  }
  for(int i = 1; i <= n; i++) {
    for(int j = 1; j <= m; j++) {
      char ch;
      cin >> ch;
      if(ch == '.') {
        ch = 0;
      } else if(ch == '*') {
        ch = 1;
      } else if(ch == 'D') {
        ch = 2;
      } else if(ch == 'I') {
        si = i, sj = j;
      } else {
        ei = i, ej = j;
      }
      mat[i][j] = ch;
    }
  }
  for(int i = 1; i <= n; i++) {
    for(int j = 1; j <= m; j++) {
      if(mat[i][j] == 2) {
        dp[i][j] = 0;
      } else {
        dp[i][j] = min({dp[i][j] - 1, dp[i - 1][j], dp[i][j - 1]}) + 1;
      }
    }
  }
  for(int i = n; i >= 1; i--) {
    for(int j = m; j >= 1; j--) {
      if(mat[i][j] == 2) {
        dp[i][j] = 0;
      } else {
        dp[i][j] = min({dp[i][j] - 1, dp[i + 1][j], dp[i][j + 1]}) + 1;
      }
    }
  }
  for(int i = 1; i <= n; i++) {
    for(int j = m; j > 0; j--) {
      if(mat[i][j] == 2) {
        dp[i][j] = 0;
      } else {
        dp[i][j] = min({dp[i][j] - 1, dp[i - 1][j], dp[i][j + 1]}) + 1;
      }
    }
  }
  for(int i = n; i >= 1; i--) {
    for(int j = 1; j <= m; j++) {
      if(mat[i][j] == 2) {
        dp[i][j] = 0;
      } else {
        dp[i][j] = min({dp[i][j] - 1, dp[i + 1][j], dp[i][j - 1]}) + 1;
      }
    }
  }
  int l = 0, r = 1e9, ans = -1;
  while(l <= r) {
    int mid = (l + r) / 2;
    if(check(mid)) {
      ans = mid;
      l = mid + 1;
    } else {
      r = mid - 1;
    }
  }
  cout << ans;
  return 0;
}