Cod sursa(job #2033614)

Utilizator OldpugAlex Ionescu Oldpug Data 7 octombrie 2017 02:14:40
Problema Barbar Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.02 kb
#include <fstream>
#include <queue>

int c, r, map[1001][1001];
bool seen[1001][1001];
std::queue<std::pair<int, int>> que;
std::pair<int, int> entry, end, *dir = new std::pair<int, int>[4]{{-1, 0}, {0, -1}, {1, 0}, {0, 1}};

bool Lee(int k)
{
  for (auto i = 1; i <= c; ++i)
    for (auto j = 1; j <= r; ++j)
      seen[i][j] = 0;

  que.push(entry);
  while (!que.empty())
  {
    auto crr = que.front();
    que.pop();

    for (auto i = 0; i < 4; ++i)
    {
      auto temp = std::make_pair(crr.first + dir[i].first, crr.second + dir[i].second);

      if (!seen[temp.first][temp.second] && temp.first > 0 && temp.first <= c && temp.second > 0 && temp.second <= r && map[temp.first][temp.second] > k)
      {
        seen[temp.first][temp.second] = 1;
        que.push(temp);
      }
    }
  }

  return seen[end.first][end.second];
}

int main()
{
  std::ifstream in("barbar.in");
  in >> c >> r;

  for (auto i = 1; i <= c; ++i)
    for (auto j = 1; j <= r; ++j)
    {
      char a;
      in >> a;

      if (a == 'D')
      {
        seen[i][j] = -1;
        que.push(std::make_pair(i, j));
      }
      if (a == '*')
        seen[i][j] = -1;
      if (a == 'I')
        entry = std::make_pair(i, j);
      if (a == 'O')
        end = std::make_pair(i, j);
    }

  while (!que.empty())
  {
    auto crr = que.front();
    que.pop();

    for (auto i = 0; i < 4; ++i)
    {
      auto temp = std::make_pair(crr.first + dir[i].first, crr.second + dir[i].second);

      if (!seen[temp.first][temp.second] && temp.first > 0 && temp.first <= c && temp.second > 0 && temp.second <= r)
      {
        seen[temp.first][temp.second] = 1;
        map[temp.first][temp.second] = map[crr.first][crr.second] + 1;
        que.push(temp);
      }
    }
  }

  auto right = 1024;
  auto left = map[entry.first][entry.second];
  int mid;

  while (right - left > 1)
  {
    mid = (left + right) / 2;
    if (Lee(mid))
      left = mid;
    else
      right = mid;
  }

  while (!Lee(mid))
    --mid;

  while (Lee(mid))
    ++mid;

  std::ofstream("barbar.out") << mid;
}