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

#include <algorithm>
#include <cmath>
#include <deque>
#include <iostream>
#include <limits>
#include <string>
#include <tuple>
#include <utility>
#include <vector>

using namespace std;
using i64 = std::int64_t;
#define rep(i, s, n) for (i64 i = (s); i < (n); ++i)

const vector<i64> kDi{-1, 1, 0, 0};
const vector<i64> kDj{0, 0, -1, 1};

int main() {
  i64 h, w, ch, cw, dh, dw;
  cin >> h >> w;
  cin >> ch >> cw;
  cin >> dh >> dw;
  --ch;
  --cw;
  --dh;
  --dw;
  vector<string> s(h);
  rep(i, 0, h) { cin >> s[i]; }
  // count, i, j
  deque<tuple<i64, i64, i64>> q{};
  q.push_back(make_tuple(0, ch, cw));
  while (!q.empty()) {
    const auto [count, i, j] = q.front();
    q.pop_front();
    if (i == dh && j == dw) {
      cout << count << endl;
      return 0;
    }
    if (s[i][j] != '.') {
      continue; // Already traversed.
    }
    s[i][j] = 'X'; // Block.
    rep(d, 0, 4) {
      const auto ii = i + kDi[d];
      const auto jj = j + kDj[d];
      if (0 <= ii && ii < h && 0 <= jj && jj < w && s[ii][jj] == '.') {
        q.push_front(make_tuple(count, ii, jj));
      }
    }
    rep(di, -2, 3) {
      rep(dj, -2, 3) {
        const auto ii = i + di;
        const auto jj = j + dj;
        if (0 <= ii && ii < h && 0 <= jj && jj < w && s[ii][jj] == '.') {
          q.push_back(make_tuple(count + 1, ii, jj));
        }
      }
    }
  }
  cout << -1 << endl;

  return 0;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <iostream>
#include <limits>
#include <string>
#include <utility>
#include <vector>

using namespace std;
using i64 = std::int64_t;

template <typename T>
bool should_step(const i64 i, const i64 j, const vector<vector<bool>> &s,
                 const vector<vector<T>> &counts, const int count, const i64 h,
                 const i64 w, const i64 dh, const i64 dw) {
  return (count < counts[dh][dw]) && (0 <= i) && (i < h) && (0 <= j) &&
         (j < w) && s[i][j] && (count < counts[i][j]);
}
template <typename T>
void traverse(const i64 i, const i64 j, const vector<vector<bool>> &s,
              vector<vector<T>> &counts, const i64 dh, const i64 dw,
              const i64 h, const i64 w) {
  if (i == dh && j == dw) {
    return;
  }
  const auto count = counts[i][j];
  const i64 zero = 0;
  for (i64 i_new = max(i - 2, zero); i_new < min(i + 3, h); ++i_new) {
    for (i64 j_new = max(j - 2, zero); j_new < min(j + 3, w); ++j_new) {
      if (should_step(i_new, j_new, s, counts, count + 1, h, w, dh, dw)) {
        counts[i_new][j_new] = count + 1;
        traverse(i_new, j_new, s, counts, dh, dw, h, w);
      }
    }
  }
  if (should_step(i - 1, j, s, counts, count, h, w, dh, dw)) {
    counts[i - 1][j] = count;
    traverse(i - 1, j, s, counts, dh, dw, h, w);
  }
  if (should_step(i + 1, j, s, counts, count, h, w, dh, dw)) {
    counts[i + 1][j] = count;
    traverse(i + 1, j, s, counts, dh, dw, h, w);
  }
  if (should_step(i, j - 1, s, counts, count, h, w, dh, dw)) {
    counts[i][j - 1] = count;
    traverse(i, j - 1, s, counts, dh, dw, h, w);
  }
  if (should_step(i, j + 1, s, counts, count, h, w, dh, dw)) {
    counts[i][j + 1] = count;
    traverse(i, j + 1, s, counts, dh, dw, h, w);
  }
}

int main() {
  i64 h, w, ch, cw, dh, dw;
  cin >> h >> w;
  cin >> ch >> cw;
  cin >> dh >> dw;
  --ch;
  --cw;
  --dh;
  --dw;
  vector<vector<bool>> s(h);
  for (i64 i = 0; i < h; ++i) {
    for (i64 j = 0; j < w; ++j) {
      char sij;
      cin >> sij;
      s[i].push_back(sij == '.');
    }
  }
  vector<vector<int>> counts(h);
  for (i64 i = 0; i < h; ++i) {
    for (i64 j = 0; j < w; ++j) {
      counts[i].push_back(numeric_limits<int>::max());
    }
  }
  counts[ch][cw] = 0;
  traverse(ch, cw, s, counts, dh, dw, h, w);
  cout << ((counts[dh][dw] == numeric_limits<int>::max()) ? -1 : counts[dh][dw])
       << endl;

  return 0;
}