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

#include <bits/stdc++.h>
#define ll long long
#define MODV 1000000007
#define INFLL LLONG_MAX // 9223372036854775807
#define EPS 1e-9
#define rep(i, n) for (ll i = 0, i##_len = (ll)(n); i < i##_len; i++)
#define repf(i, n) for (ll i = 1, i##_len = (ll)(n + 1); i < i##_len; i++)
#define all(v) v.begin(), v.end()
#define endl "\\n"
#define vi vector<ll>
#define vvi vector<vector<ll>>
#define Yes() cout << "Yes" << endl
#define YES() cout << "YES" << endl
#define No() cout << "No" << endl
#define NO() cout << "NO" << endl
#define Init()                                                                 \\
  std::ios::sync_with_stdio(false);                                            \\
  std::cin.tie(0);                                                             \\
  std::cout << fixed << setprecision(15);
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return 1;
  }
  return 0;
}
using namespace std;

ll dfs(ll h, ll w, ll ch, ll cw, ll dh, ll dw, vector<string> &s) {
  // {{y, x}, ワープ回数
  deque<pair<pair<ll, ll>, ll>> que;

  que.push_front(make_pair(make_pair(ch, cw), 0));

  // 最小壁抜け回数（-1なら未訪問）
  vvi chk(h, vi(w, -1));
  chk[ch][cw] = 0;

  // 4方向（左、右、上、下）（左上を0, 0とした場合）
  vector<long long> dx = {-1, 1, 0, 0};
  vector<long long> dy = {0, 0, -1, 1};

  // warp
  vector<long long> wdx = {-2, -1, 0,  1, 2, -2, -1, 1, 2, -2,
                           2,  -2, -1, 1, 2, -2, -1, 0, 1, 2};
  vector<long long> wdy = {2, 2,  2,  2,  2,  1,  1,  1,  1,  0,
                           0, -1, -1, -1, -1, -2, -2, -2, -2, -2};

  while (que.size()) {
    auto f = que.front();
    que.pop_front();
    // 場所と壁抜け回数
    ll y = f.first.first;
    ll x = f.first.second;
    ll cnt = f.second;
    if (chk[y][x] < cnt)
      continue;

    // 移動1
    ll dcnt = 0;
    for (ll d = 0; d < 4; d++) {
      ll tx = x + dx[d];
      ll ty = y + dy[d];
      if (tx < 0 || ty < 0 || tx >= w || ty >= h)
        continue;
      if (s[ty][tx] == '#')
        continue;
      if (chk[ty][tx] > cnt || chk[ty][tx] == -1) {
        chk[ty][tx] = cnt;
        que.push_front(make_pair(make_pair(ty, tx), cnt));
      }
    }

    // 移動2
    for (ll d = 0; d < 20; d++) {
      ll tx = x + wdx[d];
      ll ty = y + wdy[d];
      if (tx < 0 || ty < 0 || tx >= w || ty >= h)
        continue;
      if (s[ty][tx] == '#')
        continue;
      if (chk[ty][tx] > cnt + 1 || chk[ty][tx] == -1) {
        chk[ty][tx] = cnt + 1;
        que.push_back(make_pair(make_pair(ty, tx), cnt + 1));
      }
    }
  }
  return chk[dh][dw];
}

int main() {
  Init();
  ll h, w, ch, cw, dh, dw;
  cin >> h >> w >> ch >> cw >> dh >> dw;
  ch--, cw--, dh--, dw--;
  vector<string> s(h);
  rep(i, h) cin >> s[i];

  // スタート地点がch, cw　ゴールがdh, dw;
  cout << dfs(h, w, ch, cw, dh, dw, s) << endl;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define ll long long
#define MODV 1000000007
#define INFLL LLONG_MAX // 9223372036854775807
#define EPS 1e-9
#define rep(i, n) for (ll i = 0, i##_len = (ll)(n); i < i##_len; i++)
#define repf(i, n) for (ll i = 1, i##_len = (ll)(n + 1); i < i##_len; i++)
#define all(v) v.begin(), v.end()
#define endl "\\n"
#define vi vector<ll>
#define vvi vector<vector<ll>>
#define Yes() cout << "Yes" << endl
#define YES() cout << "YES" << endl
#define No() cout << "No" << endl
#define NO() cout << "NO" << endl
#define Init()                                                                 \\
  std::ios::sync_with_stdio(false);                                            \\
  std::cin.tie(0);                                                             \\
  std::cout << fixed << setprecision(15);
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return 1;
  }
  return 0;
}
using namespace std;

ll dfs(ll h, ll w, ll ch, ll cw, ll dh, ll dw, vector<string> &s) {
  // {{y, x}, ワープ回数
  queue<pair<pair<ll, ll>, ll>> que;
  que.push(make_pair(make_pair(ch, cw), 0));

  // 最小壁抜け回数（-1なら未訪問）
  vvi chk(h, vi(w, -1));
  chk[ch][cw] = 0;

  // 4方向（左、右、上、下）（左上を0, 0とした場合）
  vector<long long> dx = {-1, 1, 0, 0};
  vector<long long> dy = {0, 0, -1, 1};

  // warp
  vector<long long> wdx = {-2, -1, 0,  1, 2, -2, -1, 1, 2, -2,
                           2,  -2, -1, 1, 2, -2, -1, 0, 1, 2};
  vector<long long> wdy = {2, 2,  2,  2,  2,  1,  1,  1,  1,  0,
                           0, -1, -1, -1, -1, -2, -2, -2, -2, -2};

  while (que.size()) {
    auto f = que.front();
    que.pop();
    // 場所と壁抜け回数
    ll y = f.first.first;
    ll x = f.first.second;
    ll cnt = f.second;
    if (chk[y][x] < cnt)
      continue;

    // 移動1
    ll dcnt = 0;
    for (ll d = 0; d < 4; d++) {
      ll tx = x + dx[d];
      ll ty = y + dy[d];
      if (tx < 0 || ty < 0 || tx >= w || ty >= h)
        continue;
      if (s[ty][tx] == '#')
        continue;
      dcnt++;
      if (chk[ty][tx] > cnt || chk[ty][tx] == -1) {
        chk[ty][tx] = cnt;
        que.push(make_pair(make_pair(ty, tx), cnt));
      }
    }

    if (dcnt >= 3)
      continue;
    // 移動2
    for (ll d = 0; d < 20; d++) {
      ll tx = x + wdx[d];
      ll ty = y + wdy[d];
      if (tx < 0 || ty < 0 || tx >= w || ty >= h)
        continue;
      if (s[ty][tx] == '#')
        continue;
      if (chk[ty][tx] > cnt + 1 || chk[ty][tx] == -1) {
        chk[ty][tx] = cnt + 1;
        que.push(make_pair(make_pair(ty, tx), cnt + 1));
      }
    }
  }
  return chk[dh][dw];
}

int main() {
  Init();
  ll h, w, ch, cw, dh, dw;
  cin >> h >> w >> ch >> cw >> dh >> dw;
  ch--, cw--, dh--, dw--;
  vector<string> s(h);
  rep(i, h) cin >> s[i];

  // スタート地点がch, cw　ゴールがdh, dw;
  cout << dfs(h, w, ch, cw, dh, dw, s) << endl;
}