Cod sursa(job #2627776)

Utilizator euyoTukanul euyo Data 12 iunie 2020 15:16:47
Problema Barbar Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.67 kb
#include <cstdio>
#include <queue>
#define LIM 1000

using namespace std;

int T[LIM + 2][LIM + 2];
int dist[LIM + 2][LIM + 2]; 
char viz[LIM + 2][LIM + 2];
queue<int> ql;
queue<int> qc;

int DX[4] = { 0, 1, 0, -1 };
int DY[4] = { 1, 0, -1, 0 };

int n, m;

void lee() {
  int i, j, l, c, ln, cn;

  for ( i = 1; i <= n; ++i ) {
    for ( j = 1; j <= m; ++j ) {
	  if ( T[i][j] == 'D' ) {
		ql.push( i );
		qc.push( j );
		viz[i][j] = 1;
	    dist[i][j] = 0;
	  }
	}
  }
  while ( !ql.empty() ) {
	l = ql.front();
    c = qc.front();
	ql.pop();
	qc.pop();
	for ( i = 0; i < 4; ++i ) {
      ln = l + DX[i];
	  cn = c + DY[i];
	  if ( !viz[ln][cn] && (T[ln][cn] == '.' || T[ln][cn] == 'I' || T[ln][cn] == 'O') ) {
        dist[ln][cn] = dist[l][c] + 1;
		viz[ln][cn] = 1;
		ql.push( ln );
		qc.push( cn );
	  }
	}
  }
}

int maxim, li, ci, lo, co;

static inline void refresh() {
  int i, j;
  
  for ( i = 1; i <= n; ++i ) {
	for ( j = 1; j <= m; ++j ) {
	  viz[i][j] = 0;
	}
  }
  while ( !ql.empty() ) {
	ql.pop();
	qc.pop();
  }
}

int isWay( int d ) {
  int l = -1, c = -1, i, ln, cn;

  ql.push( li );
  qc.push( ci );
  viz[li][ci] = 1;
  if ( dist[li][ci] >= d ) {
    while ( !ql.empty() && (l != lo || c != co) ) {
	  l = ql.front();
      c = qc.front();
	  ql.pop();
	  qc.pop();
	  for ( i = 0; i < 4; ++i ) {
        ln = l + DX[i];
	    cn = c + DY[i];
	    if ( !viz[ln][cn] && dist[ln][cn] >= d && (T[ln][cn] == '.' || T[ln][cn] == 'I' || T[ln][cn] == 'O') ) {
		  viz[ln][cn] = 1;
		  ql.push( ln );
		  qc.push( cn );
	    }
	  }
    }
  }
  refresh();
  if ( l == lo && c == co ) { 
    return 1;
  } 
  return 0;
}

int cautbin() {
  int mij, st = 1, dr = maxim;

  while ( dr - st > 1 ) {
    mij = (st + dr) / 2;
	if ( isWay( mij ) ) {
      st = mij;
	} else {
      dr = mij;
	}
  }
  if ( isWay( st ) ) {
	return st;
  }
  return -1;
}

int main() {
  FILE *fin = fopen( "barbar.in", "r" );
  FILE *fout = fopen( "barbar.out", "w" );
  int i, j;

  fscanf( fin, "%d%d ", &n, &m );
  for ( i = 1; i <= n; ++i ) {
    for ( j = 1; j <= m; ++j ) {
      T[i][j] = fgetc( fin );
	  if ( T[i][j] == 'I' ) {
		li = i;
		ci = j;
	  } else if ( T[i][j] == 'O' ) {
		lo = i;
		co = j;
	  }
	}
	fgetc( fin );
  }
  for ( i = 0; i <= n + 1; ++i ) {
	T[i][m + 1] = T[i][0] = -1;
  }
  for ( j = 0; j <= m + 1; ++j ) {
    T[n + 1][j] = T[0][j] = -1;
  }
  lee();
  for ( i = 1; i <= n; ++i ) {
    for ( j = 1; j <= m; ++j ) {
	  //printf( "%d ", dist[i][j] );
	  if ( maxim < dist[i][j] ) {
		maxim = dist[i][j];
	  }
	  viz[i][j] = 0;
	}
	//printf( "\n" );
  }
  /*for ( i = 1; i <= maxim; ++i ) {
	 printf( "%d ", isWay( i ) );
  }*/
  fprintf( fout, "%d", cautbin() );
  fclose( fin );
  fclose( fout );
  return 0;
}