Cod sursa(job #2796924)

Utilizator teochess2017Togan Teodor-Bogdan teochess2017 Data 9 noiembrie 2021 00:21:27
Problema Barbar Scor 40
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.59 kb
#include <iostream>
#include <stdio.h>

using namespace std;

#define MAXRC 1000
#define NRDIR 4
#define INF (MAXRC * MAXRC + 1)

int minime[MAXRC + 2][MAXRC + 2], filled[MAXRC + 2][MAXRC + 2], q[MAXRC * MAXRC][2];///poate nu imi permit:), si imi e lene sa fac coada de MAXRC * 2 si sa stau sa fac mod de fiecare data cu posibilitatea considerabil de mare de a gresi
char mat[MAXRC + 2][MAXRC + 2];
int dirl[NRDIR] = {1, 0, -1, 0}, dirc[NRDIR] = {0, -1, 0, 1};

void fillminime(int l, int c){
  int p, u, cu, i, lenght, cod;
  cod = filled[l][c];
  p = 0;
  u = 1;
  q[0][0] = l;
  q[0][1] = c;
  minime[l][c] = 0;
  lenght = 1;
  while(p < u){
    cu = u;
    while(p < cu){
      for(i = 0; i < NRDIR; i++){
        if((filled[q[p][0] + dirl[i]][q[p][1] + dirc[i]] == cod) && (lenght < minime[q[p][0] + dirl[i]][q[p][1] + dirc[i]])){
          q[u][0] = q[p][0] + dirl[i];
          q[u][1] = q[p][1] + dirc[i];
          u++;
          minime[q[p][0] + dirl[i]][q[p][1] + dirc[i]] = lenght;
          filled[q[p][0] + dirl[i]][q[p][1] + dirc[i]] = cod + 1;
        }
      }
      p++;
    }
    lenght++;
  }
}
void fillcanmakeit(int& l, int& c, int& min){
  int i;
  filled[l][c] = 2;
  for(i = 0; i < NRDIR; i++){
    if((filled[l + dirl[i]][c + dirc[i]] == 1) && (min <= minime[l + dirl[i]][c + dirc[i]])){
      l += dirl[i];
      c += dirc[i];
      fillcanmakeit(l, c, min);
      l -= dirl[i];
      c -= dirc[i];
    }
  }
}
void resetfilled(int n, int m){
  int l, c;
  for(l = 1; l <= n; l++){
    for(c = 1; c <= m; c++){
      if(filled[l][c] != 0){
        filled[l][c] = 1;
      }
    }
  }
}
int cautare(int n, int m, int startl, int startc, int finall, int finalc){
  int min, max, mij, csl, csc;
  min = 0;
  if(minime[startl][startc] < minime[finall][finalc]){///incercam asa:))
    max = minime[startl][startc] + 2;
  }else{
    max = minime[finall][finalc] + 2;
  }
  while((max - min) > 1){
    mij = (max + min) / 2;
    csc = startc;
    csl = startl;
    resetfilled(n, m);
    fillcanmakeit(csl, csc, mij);
    if(filled[finall][finalc] == 1){///(=daca nu am putut sa trec prin pozitia finala)
      max = mij;
    }else{
      min = mij;
    }
  }
  return min;
}

int main()
{
    FILE *fin, *fout;
    int n, m, l, c, startl = -1, startc, finall = -1, finalc, retval;
    fin = fopen("barbar.in", "r");
    fscanf(fin, "%d%d", &n, &m);
    for(l = 1; l <= n; l++){
      mat[l][1] = fgetc(fin);
      for(c = 1; c <= m; c++){
        mat[l][c] = fgetc(fin);
        if(mat[l][c] == 'I'){
          startl = l;
          startc = c;
        }else if(mat[l][c] == 'O'){
          finall = l;
          finalc = c;
        }
        minime[l][c] = INF;
        filled[l][c] = 1;
      }
    }
    fclose(fin);
    fout = fopen("barbar.out", "w");
    if((startl != -1) && (finall != -1)){
      for(l = 1; l <= n; l++){
        for(c = 1; c <= m; c++){
          if(mat[l][c] == 'D'){
            fillminime(l, c);
          }
        }
      }
      for(l = 1; l <= n; l++){
        for(c = 1; c <= m; c++){
          if(mat[l][c] == '*'){
            filled[l][c] = 0;
          }else{
            filled[l][c] = 1;
          }
        }
      }
      retval = cautare(n, m, startl, startc, finall, finalc);
      resetfilled(n, m);
      fillcanmakeit(startl, startc, retval);
      if((filled[finall][finalc] == 2) && (retval != 0)){
        fprintf(fout, "%d", retval);
      }else{
        fprintf(fout, "-1");
      }
    }else{
      fprintf(fout, "-1");
    }
    fclose(fout);
    return 0;
}