Cod sursa(job #2779129)

Utilizator Asgari_ArminArmin Asgari Asgari_Armin Data 2 octombrie 2021 18:57:52
Problema Barbar Scor 90
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.12 kb
#include <fstream>
#include <queue>

using namespace std;

ifstream fin( "barbar.in" );
ofstream fout( "barbar.out" );

const int NMAX = 1000;
char mat[NMAX + 2][NMAX + 2];
int dist[NMAX + 2][NMAX + 2];
bool viz[NMAX + 2][NMAX + 2];
queue <pair<int, int>> q;

int dl[] = {0, 0, 1, -1};
int dc[] = {1, -1, 0, 0};

void myfill( int lin, int col, int x ){
  viz[lin][col] = 1;
  for( int dir = 0; dir < 4; ++dir )
    if( !viz[lin + dl[dir]][col + dc[dir]] && (mat[lin + dl[dir]][col + dc[dir]] == '.' || mat[lin + dl[dir]][col + dc[dir]] == 'I' || mat[lin + dl[dir]][col + dc[dir]] == 'O') && dist[lin + dl[dir]][col + dc[dir]] >= x )
      myfill(lin + dl[dir], col + dc[dir], x);
}

bool query( int x, int starti, int startj, int finishi, int finishj, int n, int m ){
  for( int i = 1; i <= n; ++i )
    for( int j = 1; j <= m; ++j )
      viz[i][j] = 0;
  if( dist[starti][startj] >= x )
    myfill(starti, startj, x);
  return viz[finishi][finishj];
}



int main() {
  int n, m, dir, i, j, starti, startj, stopi, stopj, lin, col, st, dr, med;
  fin >> n >> m;
  for( i = 1; i <= n; ++i )
    for( j = 1; j <= m; ++j ){
      fin >> mat[i][j];

      if( mat[i][j] == 'I' ){
        starti = i;
        startj = j;
      }

      if( mat[i][j] == 'O' ){
        stopi = i;
        stopj = j;
      }

      if( mat[i][j] == 'D' ) {
        q.push({i, j});
        viz[i][j] = 1;
      }
    }

  while( !q.empty() ){
    lin = q.front().first;
    col = q.front().second;
    q.pop();
    for( dir = 0; dir < 4; ++dir )
      if( !viz[lin + dl[dir]][col + dc[dir]] && (mat[lin + dl[dir]][col + dc[dir]] == '.' || mat[lin + dl[dir]][col + dc[dir]] == 'I' || mat[lin + dl[dir]][col + dc[dir]] == 'O') ){
        viz[lin + dl[dir]][col + dc[dir]] = 1;
        dist[lin + dl[dir]][col + dc[dir]] = dist[lin][col] + 1;
        q.push({lin + dl[dir], col + dc[dir]});
      }
  }

  st = 0;
  dr = n * m + 1;
  while( dr - st > 1 ){
    med = (st + dr) >> 1;
    if( !query(med, starti, startj, stopi, stopj, n, m) )
      dr = med;
    else
      st = med;
  }
  fout << st;
  return 0;
}