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

// #define DEBUGGING  // Enables DEBUG macro.
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
using u64 = unsigned long long;
#define REP(i, n) for (int i = 0; (i64)(i) < (i64)(n); ++i)

#ifndef DEBUGGING
#define debug(...)
#define DEBUG(...)
#else
template <typename T> void debug(T value) { std::cerr << value; }
template <typename T, typename... Ts> void debug(T value, Ts... args) {
  std::cerr << value << ", ";
  debug(args...);
}
#define DEBUG(...)                                                             \\
  do {                                                                         \\
    cerr << " (L" << __LINE__ << ") ";                                         \\
    cerr << #__VA_ARGS__ << ": ";                                              \\
    debug(__VA_ARGS__);                                                        \\
    cerr << endl;                                                              \\
  } while (0)
#endif

const i64 INF = 1LL << 50;
int dx[4] = {1, -1, 0, 0};
int dy[4] = {0, 0, 1, -1};
int rev[4] = {1, 0, 3, 2};

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  i64 H, W, K;
  cin >> H >> W >> K;
  pair<i64, i64> start, goal;
  cin >> start.first >> start.second;
  cin >> goal.first >> goal.second;
  start.first--;
  start.second--;
  goal.first--;
  goal.second--;

  vector<string> grid(H);
  cin.ignore();
  REP(i, H) {
    getline(cin, grid[i]);
    assert(grid[i].size() == (size_t)W);
  }

  map<tuple<int, int>, i64> distm;
  auto get_dist = [&](int r, int c) -> i64 {
    auto it = distm.find({r, c});
    if (it == distm.end())
      return INF;
    return it->second;
  };

  auto solve = [&]() -> i64 {
    deque<tuple<i64, int, int, int>> pq;
    pq.emplace_back(0LL, start.first, start.second, -1);
    while (pq.size()) {
      auto [d, r, c, dirs] = pq.front();
      d *= -1;
      pq.pop_front();
      if (grid[r][c] == '@')
        continue;
      if (get_dist(r, c) <= d)
        continue;
      if (r == goal.first && c == goal.second)
        return d;
      distm[{r, c}] = d;
      grid[r][c] = '@';
      DEBUG(r, c, d);
      REP(j, 4) {
        if ((dirs & (1 << j)) == 0)
          continue;
        for (int k = 1; k <= K; ++k) {
          int nr = r + dx[j] * k;
          int nc = c + dy[j] * k;
          if (nr < 0 || nr >= H)
            continue;
          if (nc < 0 || nc >= W)
            continue;
          if (grid[nr][nc] == '@') {
            break;
          }
          int ndirs = -1 & ~(1 << rev[j]);
          if (k < K) {
            ndirs &= ~(1 << j);
          }
          pq.emplace_back(-(d + 1), nr, nc, ndirs);
        }
      }
    }
    return -1LL;
  };
  i64 ans = solve();
  cout << ans << endl;
}


Error: TLE

Fixed submission:

// #define DEBUGGING  // Enables DEBUG macro.
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
using u64 = unsigned long long;
#define REP(i, n) for (int i = 0; (i64)(i) < (i64)(n); ++i)

#ifndef DEBUGGING
#define debug(...)
#define DEBUG(...)
#else
template <typename T> void debug(T value) { std::cerr << value; }
template <typename T, typename... Ts> void debug(T value, Ts... args) {
  std::cerr << value << ", ";
  debug(args...);
}
#define DEBUG(...)                                                             \\
  do {                                                                         \\
    cerr << " (L" << __LINE__ << ") ";                                         \\
    cerr << #__VA_ARGS__ << ": ";                                              \\
    debug(__VA_ARGS__);                                                        \\
    cerr << endl;                                                              \\
  } while (0)
#endif

const i64 INF = 1LL << 50;
int dx[4] = {1, -1, 0, 0};
int dy[4] = {0, 0, 1, -1};
int rev[4] = {1, 0, 3, 2};

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  i64 H, W, K;
  cin >> H >> W >> K;
  pair<i64, i64> start, goal;
  cin >> start.first >> start.second;
  cin >> goal.first >> goal.second;
  start.first--;
  start.second--;
  goal.first--;
  goal.second--;

  vector<string> grid(H);
  cin.ignore();
  REP(i, H) {
    getline(cin, grid[i]);
    assert(grid[i].size() == (size_t)W);
  }

  map<tuple<int, int>, i64> distm;
  auto get_dist = [&](int r, int c) -> i64 {
    auto it = distm.find({r, c});
    if (it == distm.end())
      return INF;
    return it->second;
  };

  auto solve = [&]() -> i64 {
    deque<tuple<i64, int, int>> pq;
    pq.emplace_back(0LL, start.first, start.second);
    while (pq.size()) {
      auto [d, r, c] = pq.front();
      d *= -1;
      pq.pop_front();
      if (grid[r][c] == '@')
        continue;

      if (get_dist(r, c) <= d)
        continue;
      if (r == goal.first && c == goal.second)
        return d;
      distm[{r, c}] = d;
      grid[r][c] = '@';
      DEBUG(r, c, d);
      REP(j, 4) {
        for (int k = 1; k <= K; ++k) {
          int nr = r + dx[j] * k;
          int nc = c + dy[j] * k;
          if (nr < 0 || nr >= H)
            continue;
          if (nc < 0 || nc >= W)
            continue;
          if (grid[nr][nc] == '@')
            break;
          pq.emplace_back(-(d + 1), nr, nc);
        }
      }
    }
    return -1LL;
  };
  i64 ans = solve();
  cout << ans << endl;
}