Cod sursa(job #2627029)

Utilizator victorzarzuZarzu Victor victorzarzu Data 9 iunie 2020 13:15:12
Problema Barbar Scor 20
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.78 kb
#include <bits/stdc++.h>
#define dragon 1007
#define perete -1

using namespace std;
ifstream f("barbar.in");
ofstream g("barbar.out");
int n, m, xstart, ystart, xfinish, yfinish;
char ch;
int a[1005][1005], b[1005][1005];
bool viz[1005][1005];

struct node 
{
  int x, y, dist;
};
int dx[] = {-1, 1, 0, 0};
int dy[] = {0, 0, 1, -1};
queue<node> q;

void Read()
{
  f>>n>>m;
  for(int i = 1;i <= n;++i)
    for(int j = 1;j <= m;++j)
      {
        f>>ch;
        if(ch == '*')
          b[i][j] = perete;
        else if(ch == 'D')
          a[i][j] = dragon, q.push({i, j, 0});
        else if(ch == 'I')
          xstart = i, ystart = j;
        else if(ch == 'O')
          xfinish = i, yfinish = j;
      }
}

bool is_ok(int x, int y)
{
  return (x >= 1 && y >= 1 && x <= n && y <= n && !b[x][y] && a[x][y] != dragon);
}

void Prepare()
{
  int x_new, y_new;
  while(!q.empty())
  {
    node curr = q.front();
    b[curr.x][curr.y] = curr.dist;
    q.pop();

    for(int i = 0;i < 4;++i)
      {
        x_new = curr.x + dx[i];
        y_new = curr.y + dy[i];

        if(is_ok(x_new, y_new))
          q.push({x_new, y_new, curr.dist + 1});
      }
  }
}

bool ok(int x, int y, int val)
{
  int x_new, y_new;
  if(b[x][y] < val || viz[x][y])
    return false;
  if(x == xfinish && y == yfinish)
    return true;
  bool ver = false;
  viz[x][y] = true;
  for(int i = 0;i < 4;++i)
    {
      x_new = dx[i] + x;
      y_new = dy[i] + y;
      
      ver = ver | ok(x_new, y_new, val);
    }
  return ver;
}

void Solve()
{
  int low = 0, high = 1000, rez, mid;
  while(low < high)
  {
    mid = (low + high) / 2;
    memset(viz, false, sizeof(viz));
    if(ok(xstart, ystart, mid))
      rez = mid, low = mid + 1;
    else
      high = mid - 1;
  }
  g<<rez;
}

int main()
{
  Read();
  Prepare();
  Solve();
  return 0;
}