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

#include <bits/stdc++.h>
using namespace std;
#define int long long

signed main() {
  // cout << fixed << setprecision(10) << flush;

  int h, w;
  cin >> h >> w;
  int ch, dh, cw, dw;
  cin >> ch >> cw >> dh >> dw;
  ch--;
  cw--;
  dh--;
  dw--;

  vector<vector<int>> maze(h, vector<int>(w));
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      char c;
      cin >> c;
      if (c == '#')
        maze[i][j] = 1;
      else
        maze[i][j] = 0;
    }
  }

  auto isin = [&](int i, int j) {
    return i >= 0 && i <= h - 1 && j >= 0 && j <= w - 1;
  };

  queue<int> qi;
  queue<int> qj;
  qi.push(ch);
  qj.push(cw);

  vector<vector<int>> visited(h, vector<int>(w, -1));
  visited[ch][cw] = 0;
  int warp = 0;
  queue<int> nqi;
  queue<int> nqj;
  nqi.push(ch);
  // どっかで break
  // while(visited[dh][dw] == -1 && !nqi.empty()){
  //     vector<vector<int>> warp_cand(h, vector<int>(w, -1));
  //     queue<int> vqi;
  //     queue<int> vqj;
  //     nqi = vqi;
  //     nqj = vqj;
  //     while(!qi.empty()){
  //         int nowi = qi.front();
  //         int nowj = qj.front();
  //         qi.pop();
  //         qj.pop();
  //         visited[nowi][nowj] = warp;
  //         if(nowi == dh && nowj == dw){
  //             cout << visited[dh][dw] << endl;
  //             return 0;
  //         }
  //         int di[4] = {0, 0, 1, -1};
  //         int dj[4] = {1, -1, 0, 0};
  //         for(int k=0; k<4; k++){
  //             int ni = nowi + di[k];
  //             int nj = nowj + dj[k];
  //             if(isin(ni, nj) && (visited[ni][nj] == -1 || visited[ni][nj] >
  //             warp) && maze[ni][nj] == 0){
  //                 visited[ni][nj] = warp;
  //                 if(ni == dh && nj == dw){
  //                     cout << visited[dh][dw] << endl;
  //                     return 0;
  //                 }
  //                 qi.push(ni);
  //                 qj.push(nj);
  //             }
  //         }

  //         for(int k=0; k<20; k++){
  //             int di[20] = {-2, -2, -2, -2, -2, -1, -1, -1, -1, 0, 0, 1, 1,
  //             1, 1, 2, 2, 2, 2, 2}; int dj[20] = {-2, -1, 0, 1, 2,    -2, -1,
  //             1, 2, -2,  2, -2, -1, 1, 2, -2, -1, 0, 1, 2}; int wi = nowi +
  //             di[k]; int wj = nowj + dj[k]; if(isin(wi, wj) &&
  //             visited[wi][wj] == -1 && warp_cand[wi][wj] == -1 &&
  //             maze[wi][wj] == 0){
  //                 warp_cand[wi][wj] = 0;
  //                 visited[wi][wj] = warp+1;
  //                 nqi.push(wi);
  //                 nqj.push(wj);
  //             }
  //         }
  //     }

  // for(int i=0; i<h; i++){
  //     for(int j=0; j<w; j++){
  //         if(visited[i][j] == -1 && maze[i][j] == 0){
  //             for(int ii=-2; ii<=2; ii++){
  //                 for(int jj=-2; jj<=2; jj++){
  //                     if(isin(i+ii, j+jj) && visited[i+ii][j+jj] != -1){
  //                         nqi.push(i);
  //                         nqj.push(j);
  //                     }
  //                 }
  //             }
  //         }
  //     }
  // }
  //     warp++;
  //     qi = nqi;
  //     qj = nqj;
  // }

  priority_queue<tuple<int, int, int>, vector<tuple<int, int, int>>,
                 greater<tuple<int, int, int>>>
      w_pos;
  w_pos.push(make_tuple(0, ch, cw));
  vector<vector<int>> cand_warp(h, vector<int>(w, -1));
  while (!w_pos.empty()) {
    int noww = get<0>(w_pos.top());
    int nowi = get<1>(w_pos.top());
    int nowj = get<2>(w_pos.top());
    w_pos.pop();
    if (visited[nowi][nowj] != -1 && visited[nowi][nowj] < noww)
      continue;
    visited[nowi][nowj] = noww;
    if (nowi == dh && nowj == dw) {
      cout << noww << endl;
      return 0;
    }

    int di[4] = {0, 0, 1, -1};
    int dj[4] = {1, -1, 0, 0};
    for (int k = 0; k < 4; k++) {
      int ni = nowi + di[k];
      int nj = nowj + dj[k];
      if (isin(ni, nj) && visited[ni][nj] == -1 && maze[ni][nj] == 0) {
        visited[ni][nj] = noww;
        w_pos.push(make_tuple(noww, ni, nj));
      }
    }

    for (int a = -2; a <= 2; a++) {
      for (int b = -2; b <= 2; b++) {
        int wi = nowi + a;
        int wj = nowj + b;
        if (isin(wi, wj) && visited[wi][wj] == -1 && maze[wi][wj] == 0 &&
            cand_warp[wi][wj] == -1) {
          w_pos.push(make_tuple(noww + 1, wi, wj));
        }
      }
    }
  }

  cout << visited[dh][dw] << endl;

  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
#define int long long

signed main() {
  // cout << fixed << setprecision(10) << flush;

  int h, w;
  cin >> h >> w;
  int ch, dh, cw, dw;
  cin >> ch >> cw >> dh >> dw;
  ch--;
  cw--;
  dh--;
  dw--;

  vector<vector<int>> maze(h, vector<int>(w));
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      char c;
      cin >> c;
      if (c == '#')
        maze[i][j] = 1;
      else
        maze[i][j] = 0;
    }
  }

  auto isin = [&](int i, int j) {
    return i >= 0 && i <= h - 1 && j >= 0 && j <= w - 1;
  };

  queue<int> qi;
  queue<int> qj;
  qi.push(ch);
  qj.push(cw);

  vector<vector<int>> visited(h, vector<int>(w, -1));
  visited[ch][cw] = 0;
  int warp = 0;
  queue<int> nqi;
  queue<int> nqj;
  nqi.push(ch);
  // どっかで break
  while (visited[dh][dw] == -1 && !nqi.empty()) {
    vector<vector<int>> warp_cand(h, vector<int>(w, -1));
    queue<int> vqi;
    queue<int> vqj;
    nqi = vqi;
    nqj = vqj;
    while (!qi.empty()) {
      int nowi = qi.front();
      int nowj = qj.front();
      qi.pop();
      qj.pop();
      visited[nowi][nowj] = warp;
      if (nowi == dh && nowj == dw) {
        cout << visited[dh][dw] << endl;
        return 0;
      }
      int di[4] = {0, 0, 1, -1};
      int dj[4] = {1, -1, 0, 0};
      for (int k = 0; k < 4; k++) {
        int ni = nowi + di[k];
        int nj = nowj + dj[k];
        if (isin(ni, nj) && visited[ni][nj] == -1 && maze[ni][nj] == 0) {
          visited[ni][nj] = warp;
          if (ni == dh && nj == dw) {
            cout << visited[dh][dw] << endl;
            return 0;
          }
          qi.push(ni);
          qj.push(nj);
        }
      }

      for (int k = 0; k < 20; k++) {
        int di[20] = {-2, -2, -2, -2, -2, -1, -1, -1, -1, 0,
                      0,  1,  1,  1,  1,  2,  2,  2,  2,  2};
        int dj[20] = {-2, -1, 0,  1, 2, -2, -1, 1, 2, -2,
                      2,  -2, -1, 1, 2, -2, -1, 0, 1, 2};
        int wi = nowi + di[k];
        int wj = nowj + dj[k];
        if (isin(wi, wj) && visited[wi][wj] == -1 && warp_cand[wi][wj] == -1 &&
            maze[wi][wj] == 0) {
          warp_cand[wi][wj] = 0;
          nqi.push(wi);
          nqj.push(wj);
        }
      }
    }

    // for(int i=0; i<h; i++){
    //     for(int j=0; j<w; j++){
    //         if(visited[i][j] == -1 && maze[i][j] == 0){
    //             for(int ii=-2; ii<=2; ii++){
    //                 for(int jj=-2; jj<=2; jj++){
    //                     if(isin(i+ii, j+jj) && visited[i+ii][j+jj] != -1){
    //                         nqi.push(i);
    //                         nqj.push(j);
    //                     }
    //                 }
    //             }
    //         }
    //     }
    // }
    warp++;
    qi = nqi;
    qj = nqj;
  }

  // priority_queue<tuple<int, int, int>> w_pos;
  // w_pos.push(make_tuple(0, ch, cw));
  // while(!w_pos.empty()){
  //     int noww = get<0>(w_pos.top());
  //     int nowi = get<1>(w_pos.top());
  //     int nowj = get<2>(w_pos.top());
  //     w_pos.pop();
  //     if(visited[nowi][nowj] != -1) continue;
  //     visited[nowi][nowj] = noww;
  //     if(nowi == dh && nowj == dw){
  //         cout << noww << endl;
  //         return 0;
  //     }

  //     int di[4] = {0, 0, 1, -1};
  //     int dj[4] = {1, -1, 0, 0};
  //     for(int k=0; k<4; k++){
  //         int ni = nowi + di[k];
  //         int nj = nowj + dj[k];
  //         if(isin(ni, nj) && visited[ni][nj] == -1 && maze[ni][nj] == 0){
  //             w_pos.push(make_tuple(noww, ni, nj));
  //         }
  //     }

  //     for(int a=-2; a<=2; a++){
  //         for(int b=-2; b<=2; b++){

  //         }
  //     }
  // }

  cout << visited[dh][dw] << endl;

  return 0;
}