Problem p02579 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <algorithm>
#include <iomanip>
#include <iostream>
#include <queue>
#include <string>
#include <unordered_set>
#include <vector>

using maze = std::vector<std::string>;

struct Point {
  int x;
  int y;

  Point() : x(0), y(0) {}
  Point(int x, int y) : x(x), y(y) {}

  bool operator==(const Point &rhs) const { return x == rhs.x && y == rhs.y; }
};

namespace std {

template <> struct hash<Point> {
  std::size_t operator()(const Point &p) const {
    return std::hash<int>{}(p.x) ^ std::hash<int>{}(p.y);
  }
};

} // namespace std

bool is_in(int h, int w, const Point &p) {
  return p.x >= 0 && p.x < w && p.y >= 0 && p.y < h;
}

bool move(int h, int w, const Point &p, maze &m, std::queue<Point> &q) {
  if (!is_in(h, w, p))
    return false;

  auto &v = m[p.y][p.x];
  if (v == '#' || v == 'x')
    return false;
  v = 'x';
  q.push(p);
  return true;
}

void print(const maze &m) {
  for (const auto &row : m) {
    std::cerr << row << std::endl;
  }
}

// void check_warp(int h, int w, const Point& p, maze& m)
//{
//   for (int x = std::max(0, p.x - 2); x < std::min(w, p.x + 3); ++x) {
//     for (int y = std::max(0, p.y - 2); y < std::min(h, p.y + 3); ++y) {
//       auto& v = m[y][x];
//       if (v == '.') v = 'w';
//     }
//   }
// }

int solve(int h, int w, const Point &start, const Point &goal, maze &m) {
  int result = 0;
  std::queue<Point> q;

  q.push(start);

  while (true) {
    std::unordered_set<Point> warps;
    while (!q.empty()) {
      auto p = q.front();
      q.pop();

      if (p == goal)
        return result;
      m[p.y][p.x] = 'x';

      move(h, w, Point{p.x + 1, p.y}, m, q);
      move(h, w, Point{p.x - 1, p.y}, m, q);
      move(h, w, Point{p.x, p.y + 1}, m, q);
      move(h, w, Point{p.x, p.y - 1}, m, q);

      for (int x = std::max(0, p.x - 2); x < std::min(w, p.x + 3); ++x) {
        for (int y = std::max(0, p.y - 2); y < std::min(h, p.y + 3); ++y) {
          auto &v = m[y][x];
          if (v == '.')
            warps.emplace(x, y);
        }
      }
    }

    ++result;

    for (const auto &p : warps) {
      q.push(p);
    }
    if (q.empty())
      return -1;
  }
}

int main() {
  int h, w;
  Point start, goal;
  std::cin >> h >> w >> start.y >> start.x >> goal.y >> goal.x;
  --start.x;
  --start.y;
  --goal.x;
  --goal.y;

  maze m(h);
  for (auto &row : m) {
    std::cin >> row;
  }

  std::cout << std::setprecision(20);
  std::cout << solve(h, w, start, goal, m) << std::endl;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <iomanip>
#include <iostream>
#include <queue>
#include <string>
#include <vector>

using maze = std::vector<std::string>;

struct Point {
  int x;
  int y;

  bool operator==(const Point &rhs) const { return x == rhs.x && y == rhs.y; }
};

bool is_in(int h, int w, const Point &p) {
  return p.x >= 0 && p.x < w && p.y >= 0 && p.y < h;
}

bool move(int h, int w, const Point &p, maze &m, std::queue<Point> &q) {
  if (!is_in(h, w, p))
    return false;

  auto &v = m[p.y][p.x];
  if (v == '#' || v == 'x')
    return false;
  v = 'x';
  q.push(p);
  return true;
}

void print(const maze &m) {
  for (const auto &row : m) {
    std::cerr << row << std::endl;
  }
}

void check_warp(int h, int w, const Point &p, maze &m) {
  for (int x = std::max(0, p.x - 2); x < std::min(w, p.x + 3); ++x) {
    for (int y = std::max(0, p.y - 2); y < std::min(h, p.y + 3); ++y) {
      auto &v = m[y][x];
      if (v == '.')
        v = 'w';
    }
  }
}

int solve(int h, int w, const Point &start, const Point &goal, maze &m) {
  int result = 0;
  std::queue<Point> q;

  q.push(start);

  while (true) {
    while (!q.empty()) {
      auto p = q.front();
      q.pop();

      if (p == goal)
        return result;
      m[p.y][p.x] = 'x';
      check_warp(h, w, p, m);
      move(h, w, Point{p.x + 1, p.y}, m, q);
      move(h, w, Point{p.x - 1, p.y}, m, q);
      move(h, w, Point{p.x, p.y + 1}, m, q);
      move(h, w, Point{p.x, p.y - 1}, m, q);
    }

    ++result;

    for (int y = 0; y < h; ++y) {
      for (int x = 0; x < w; ++x) {
        if (m[y][x] == 'w') {
          q.push(Point{x, y});
        }
      }
    }
    if (q.empty())
      return -1;
  }
}

int main() {
  int h, w;
  Point start, goal;
  std::cin >> h >> w >> start.y >> start.x >> goal.y >> goal.x;
  --start.x;
  --start.y;
  --goal.x;
  --goal.y;

  maze m(h);
  for (auto &row : m) {
    std::cin >> row;
  }

  std::cout << std::setprecision(20);
  std::cout << solve(h, w, start, goal, m) << std::endl;
}