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

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using P = pair<int, int>;
const int INF = 1001001001;
const ll LINF = 1LL << 60;
const int MOD = 1'000'000'007;

template <typename T> void print(const T &v) {
  for (int i = 0; i < v.size(); i++) {
    if (i)
      cout << ' ';
    cout << v[i];
  }
  cout << endl;
}

template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}

template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}

int main() {
  int h, w, ch, cw, dh, dw;
  cin >> h >> w >> ch >> cw >> dh >> dw;
  --ch;
  --cw;
  --dh;
  --dw;
  vector<vector<char>> grid(h, vector<char>(w));
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      cin >> grid[i][j];
    }
  }
  vector<vector<int>> score(h, vector<int>(w, INF));
  score[ch][cw] = 0;
  //
  queue<P> stop_list;
  set<P> stop_check;
  //
  queue<P> start_list;
  set<P> start_check;
  //
  start_list.push(make_pair(ch, cw));
  start_check.insert(make_pair(ch, cw));

  while (!start_list.empty()) {
    P start = start_list.front();
    start_list.pop();
    queue<P> qe;
    qe.push(start);
    // 幅優先探索で連続空間を網羅する
    while (!qe.empty()) {
      P now = qe.front();
      qe.pop();
      int x = now.first;
      int y = now.second;
      int xs[4] = {1, -1, 0, 0};
      int ys[4] = {0, 0, 1, -1};
      for (int i = 0; i < 4; i++) {
        int nx = x + xs[i];
        int ny = y + ys[i];
        // 範囲内確認
        if (nx < 0 || ny < 0 || nx >= h || ny >= w) {
          continue;
        }
        // 壁かどうかを確認
        if (grid[nx][ny] == '#') {
          if (!stop_check.count(make_pair(x, y))) {
            stop_list.push(make_pair(x, y));
            stop_check.insert(make_pair(x, y));
          }
          continue;
        }
        // 既に探索済かを確認する
        if (score[nx][ny] <= score[x][y]) {
          continue;
        }
        score[nx][ny] = min(score[nx][ny], score[x][y]);
        qe.push(make_pair(nx, ny));
      }
    }
    // 魔法で未到達箇所に移動できるか確認する
    while (!stop_list.empty()) {
      P now = stop_list.front();
      stop_list.pop();
      int x = now.first;
      int y = now.second;
      int xs[20] = {-2, -2, -2, -2, -2, -1, -1, -1, -1, 0,
                    0,  1,  1,  1,  1,  2,  2,  2,  2,  2};
      int ys[20] = {-2, -1, 0,  1, 2, -2, -1, 1, 2, -2,
                    2,  -2, -1, 1, 2, -2, -1, 0, 1, 2};
      for (int i = 0; i < 20; i++) {
        int nx = x + xs[i];
        int ny = y + ys[i];
        // 範囲内確認
        if (nx < 0 || ny < 0 || nx >= h || ny >= w) {
          continue;
        }
        // 壁かを確認
        if (grid[nx][ny] == '#') {
          continue;
        }
        // 訪問済かを確認
        if (score[nx][ny] != INF) {
          continue;
        }
        if (!start_check.count(make_pair(nx, ny))) {
          score[nx][ny] = min(score[nx][ny], score[x][y] + 1);
          start_list.push(make_pair(nx, ny));
          start_check.insert(make_pair(nx, ny));
        }
      }
    }
  }
  if (score[dh][dw] == INF) {
    cout << -1 << endl;
  } else {
    cout << score[dh][dw] << endl;
  }
  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using P = pair<int, int>;
const int INF = 1001001001;
const ll LINF = 1LL << 60;
const int MOD = 1'000'000'007;

template <typename T> void print(const T &v) {
  for (int i = 0; i < v.size(); i++) {
    if (i)
      cout << ' ';
    cout << v[i];
  }
  cout << endl;
}

template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}

template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}

const ll BIG = 100'000'000;
int main() {
  int h, w;
  cin >> h >> w;
  int ch, cw, dh, dw;
  cin >> ch >> cw >> dh >> dw;
  --ch;
  --cw;
  --dh;
  --dw;
  vector<vector<char>> grid(h, vector<char>(w));
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      cin >> grid[i][j];
    }
  }

  vector<vector<bool>> seen(h, vector<bool>(w, false));
  vector<vector<ll>> score(h, vector<ll>(w, LINF));
  seen[ch][cw] = true;
  score[ch][cw] = 0;
  queue<P> st;
  st.push(make_pair(ch, cw));

  // x: 縦，y: 横
  while (!st.empty()) {
    P now = st.front();
    st.pop();
    int x = now.first;
    int y = now.second;
    int xs[24] = {0,  0, -1, 1, -2, -2, -2, -2, -2, -1, -1, -1,
                  -1, 0, 0,  1, 1,  1,  1,  2,  2,  2,  2,  2};
    int ys[24] = {1, -1, 0, 0,  -2, -1, 0, 1,  2,  -2, -1, 1,
                  2, -2, 2, -2, -1, 1,  2, -2, -1, 0,  1,  2};

    for (int i = 0; i < 24; i++) {
      int nx = x + xs[i];
      int ny = y + ys[i];

      // グリッドの範囲チェック
      if (nx < 0 || ny < 0 || nx >= h || ny >= w) {
        continue;
      }
      // 壁かどうかチェック
      if (grid[nx][ny] == '#') {
        continue;
      }
      if (score[x][y] >= score[nx][ny]) {
        continue;
      }
      // 移動距離に応じてコストを変動
      if (i < 4) {
        score[nx][ny] = score[x][y] + 1;
      } else {
        score[nx][ny] = score[x][y] + BIG;
      }
      if (seen[nx][ny]) {
        continue;
      } else {
        st.push(make_pair(nx, ny));
      }
      // 探索済でなければ探索済にする
      // seen[nx][ny] = true;
    }
  }
  if (score[dh][dw] == LINF) {
    cout << -1 << endl;
  } else {
    cout << score[dh][dw] / BIG << endl;
  }

  return 0;
}