Cod sursa(job #2508618)

Utilizator Florinos123Gaina Florin Florinos123 Data 12 decembrie 2019 16:36:20
Problema Barbar Scor 90
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.87 kb
#include <iostream>
#include <fstream>
#include <queue>

using namespace std;

ifstream f ("barbar.in");
ofstream g ("barbar.out");

int n, m, i, j, a[1005][1005], drum[1005][1005], maxim;
int startx, starty, stopx, stopy, vizitat[1005][1005], nr;
int di[4] = {0,1,-1,0};
int dj[4] = {1,0,0,-1};
queue < pair < int, int > > coada;

void read ()
{
    char c;
      f >> n >> m;
       for (i=1; i<=n; i++)
         for (j=1; j<=m; j++)
       {
           f >> c;
           if (c == '*')
             a[i][j] = -1;
           if (c == 'D')
           {
               a[i][j] = -1;
               coada.push(make_pair(i, j));
           }
           if (c == 'I')
           {
               startx = i;
               starty = j;
           }
           if (c == 'O')
           {
               stopx = i;
               stopy = j;
           }
       }
}

bool ok (int i, int j)
{
    if (i<1 || j<1 || i>n || j>m)
        return false;
    if (a[i][j] == -1)
        return false;
    return true;
}

void distante ()
{
    int i_nou, j_nou, dist;
     while (!coada.empty())
     {
         i = coada.front().first;
         j = coada.front().second;
         coada.pop();
          for (dist=0; dist<4; dist++)
          {
              i_nou = i + di[dist];
              j_nou = j + dj[dist];
               if (ok(i_nou, j_nou) && drum[i_nou][j_nou] == 0)
               {
                   drum[i_nou][j_nou] = drum[i][j] + 1;
                   if (drum[i_nou][j_nou] > maxim)
                         maxim = drum[i_nou][j_nou];
                   coada.push(make_pair(i_nou, j_nou));
               }
          }
     }
}

bool lee (int val, int nr)
{
    if (drum[stopx][stopy] < val)
         return false;
       else {
    int i_nou, j_nou, dist;
    while (!coada.empty())
        coada.pop();
    coada.push(make_pair(startx, starty));
     while (!coada.empty())
     {
        i = coada.front().first;
        j = coada.front().second;
        coada.pop();
         for (dist=0; dist<4; dist++)
         {
             i_nou = i + di[dist];
             j_nou = j + dj[dist];
               if (ok(i_nou, j_nou) && drum[i_nou][j_nou] >= val && vizitat[i_nou][j_nou] != nr)
               {
                   vizitat[i_nou][j_nou] = nr;
                   coada.push(make_pair(i_nou, j_nou));
               }
         }
     }
   if (vizitat[stopx][stopy] == nr)
          return true;
   return false;
 }
}

void task ()
{
    int st = 1, dr = maxim, mij, poz = -1;
     while (st <= dr)
     {
         mij = (st + dr)/2;
         nr ++;
         if (lee(mij, nr) > 0)
         {
             poz = mij;
             st = mij + 1;
         }
          else
               dr = mij - 1;
     }
     g << poz;
}

int main()
{
   read();
   distante();
   task();
    return 0;
}