Cod sursa(job #1570569)

Utilizator PTAdrian64Pop-Tifrea Adrian PTAdrian64 Data 16 ianuarie 2016 17:20:26
Problema Barbar Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.81 kb
#include <cstring>
#include <fstream>
#include <algorithm>
#define inf 0x3f3f3f3f

#define LIBER '.'
#define PERETE '*'
#define DRAGON 'D'
#define START 'I'
#define FINAL 'O'

#define maxrc 1002
#include <vector>
#include <queue>

using namespace std;

int R,C;
char a[maxrc][maxrc];  ///matrice pentru memorarea temnitei
int dist[maxrc][maxrc];   ///dist[i][j] = cea mai mica distanta la care se afla un dragon fata de a[i][j]
int dirx[] = {-1,0,1,0},diry[] = {0,1,0,-1};
int xs,ys,xf,yf;
bool viz[maxrc][maxrc];

vector <pair<int,int> > V;
queue <pair<int,int> > Q;

bool incadrare(const int &x,const int &y){
  if(x >= 1 && x <= C && y >= 1 && y <= R)return true;
  return false;
}

bool valoare_valida(int val){
  if(dist[ys][xs] < val)return false;

  Q.push(make_pair(xs,ys));
  memset(viz,false,sizeof(viz));
  viz[ys][xs] = true;
  int x,y;
  while(!Q.empty()){
    x = Q.front().first;
    y = Q.front().second;
    Q.pop();
    for(int i = 0;i < 4;i++)
      if(incadrare(x + dirx[i],y + diry[i])){
       if(viz[y + diry[i]][x + dirx[i]] == false && dist[y + diry[i]][x + dirx[i]] >= val){

        viz[y + diry[i]][x + dirx[i]] = true;
        Q.push(make_pair(x + dirx[i],y + diry[i]));
       }
      }
   }


  return viz[yf][xf];
}

int main(){

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

    fin >> R >> C;
    int i,j,x,y;
    for(i = 1;i <= R;i++){

      for(j = 1;j <= C;j++){

        dist[i][j] = inf;
        fin >> a[i][j];
        switch(a[i][j]){
          case LIBER:
            break;
          case PERETE:
            break;
          case DRAGON:
            Q.push(make_pair(j,i));
            dist[i][j] = 0;
            break;
          case START:
            a[i][j] = LIBER;
            xs = j;
            ys = i;
            break;
          case FINAL:
            a[i][j] = LIBER;
            xf = j;
            yf = i;
            break;
        }

      }

    }

    ///verificam ca merge citirea: OK

    ///calculam dist: OK
    ///calculam maxd: OK
    int maxv;  ///maxd = cea mai mare valoare intalnita in matricea dist
      maxv = -inf;
      while(!Q.empty()){

        x = Q.front().first;
        y = Q.front().second;
        Q.pop();
        maxv = max(maxv,dist[y][x]);
        for(i = 0;i < 4;i++)
           if(incadrare(x + dirx[i],y + diry[i]) && a[y + diry[i]][x + dirx[i]] == LIBER){
             if(dist[y + diry[i]][x + dirx[i]] > dist[y][x] + 1){
               dist[y + diry[i]][x + dirx[i]] = dist[y][x] + 1;
               Q.push(make_pair(x + dirx[i],y + diry[i]));
             }
           }

      }

    int sol = -1,li = 0,lf = maxv,m;
    ///determinam solutia:
    while(li <= lf){
      m = li + (lf - li)/2;
      if(valoare_valida(m)){
         sol = m;
         li = m + 1;
      }
      else {
        lf = m - 1;
      }

    }

    fout << sol<<"\n";


    return 0;
}