Cod sursa(job #2796891)

Utilizator teochess2017Togan Teodor-Bogdan teochess2017 Data 8 noiembrie 2021 23:06:35
Problema Barbar Scor 20
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.99 kb
#include <iostream>
#include <stdio.h>

using namespace std;

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

int mat[MAXRC + 2][MAXRC + 2], minime[MAXRC + 2][MAXRC + 2], filled[MAXRC + 2][MAXRC + 2], q[MAXRC * MAXRC][2];///pentru ca 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
int dirl[NRDIR] = {1, 0, -1, 0}, dirc[NRDIR] = {0, -1, 0, 1};

void fillminime(int l, int c, int cod){
  int p, u, cu, i, lenght;
  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;
  max = n + m;///incercam asa:))
  while((max - min) > 1){
    mij = (max + min) / 2;
    csc = startc;
    csl = startl;
    resetfilled(n, m);
    fillcanmakeit(csc, csl, 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, cod, startl, startc, finall, finalc;
    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] != '*'){
          if(mat[l][c] == 'I'){
            startl = l;
            startc = c;
          }else if(mat[l][c] == 'O'){
            finall = l;
            finalc = c;
          }
          filled[l][c] = 1;
          minime[l][c] = INF;
        }
      }
    }
    fclose(fin);
    cod = 1;
    for(l = 1; l <= n; l++){
      for(c = 1; c <= m; c++){
        if(mat[l][c] == 'D'){
          fillminime(l, c, cod);
          cod++;
        }
      }
    }
    fout = fopen("barbar.out", "w");
    fprintf(fout, "%d", cautare(n, m, startl, startc, finall, finalc));
    fclose(fout);
    return 0;
}