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

#include <cmath>
#include <deque>
#include <iostream>
#include <vector>
using namespace std;

int judge_ikeru(int h, int w, int max_h, int max_w);

int main() {
  int H, W;
  int Sh, Sw;
  int Gh, Gw;
  char cell;
  int now_h, now_w;
  int judge;
  long long count = 0;
  vector<int> temp_v(4), now_v(4);
  deque<vector<int>> q_maze;

  std::cin >> H >> W >> Sh >> Sw >> Gh >> Gw;
  Sh = Sh - 1;
  Sw = Sw - 1;
  Gh = Gh - 1;
  Gw = Gw - 1;
  int ans = -1;

  now_h = Sh;
  now_w = Sw;

  vector<vector<int>> maze;
  vector<int> v(W);

  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      std::cin >> cell;
      if (cell == '#') {
        // # = 1は壁
        v[j] = 1;
      } else {
        v[j] = 0;
      }
    }
    maze.push_back(v);
  }
  // ここまでインプット

  // 最初だけ
  temp_v = {now_h, now_w, 0, 0};
  q_maze.push_front(temp_v);
  maze[now_h][now_w] = 1;

  while (q_maze.size() != 0) {
    // 左の状態を取得
    now_v = q_maze[0];
    q_maze.pop_front();
    // goal判定
    if (now_v[0] == Gh && now_v[1] == Gw) {
      if (now_v[3] > ans) {
        ans = now_v[3];
        break;
      }
    } else if (now_v[2] == 1 && maze[now_v[0]][now_v[1]] == 1) {
      // テレポで来たけど既にコス0で来られていた場合何もしない
      //  std::cout << "bug" << now_h << " " << now_w << " " <<
      //  maze[now_h][now_w] << "\\n";
    } else {
      // ゴールに行ったら派生しない
      now_h = now_v[0];
      now_w = now_v[1];

      for (int i = -2; i <= 2; i++) {
        for (int j = -2; j <= 2; j++) {
          if (i != 0 || j != 0) {
            // 自分の立ち位置はさすがにだめ
            judge = judge_ikeru(now_h + i, now_w + j, H - 1, W - 1);
            if (judge == 1) {
              // 端っこじゃなければさらに判定
              if (labs((long long)i) + labs((long long)j) == 1) {
                // コス0移動の場合
                if (maze[now_h + i][now_w + j] != 1) {
                  maze[now_h + i][now_w + j] = 1;
                  temp_v = {now_h + i, now_w + j, 0, now_v[3]};
                  q_maze.push_front(temp_v);
                }
              } else {
                // テレポ移動の場合
                if (maze[now_h + i][now_w + j] == 0) {
                  maze[now_h + i][now_w + j] = 2;
                  temp_v = {now_h + i, now_w + j, 1, now_v[3] + 1};
                  q_maze.push_back(temp_v);
                }
              }
            }
          }
        }
      }

      count++;
    }

    if (count > W * H) {
      break;
    }
  }

  if (ans == W * H) {
    std::cout << -1;
  } else {
    std::cout << ans;
  }
}

int judge_ikeru(int h, int w, int max_h, int max_w) {
  int ans = 1;

  if (h < 0 || h > max_h || w < 0 || w > max_w) {
    ans = 0;
  }
  return ans;
}

Error: TLE

Fixed submission:

#include <cmath>
#include <deque>
#include <iostream>
#include <vector>
using namespace std;

int judge_ikeru(int h, int w, vector<vector<int>> maze);

int main() {
  int H, W;
  int Sh, Sw;
  int Gh, Gw;
  char cell;
  int now_h, now_w;
  int judge;
  long long count = 0;
  vector<int> temp_v(4), now_v(4);
  deque<vector<int>> q_maze;

  std::cin >> H >> W >> Sh >> Sw >> Gh >> Gw;
  Sh = Sh - 1;
  Sw = Sw - 1;
  Gh = Gh - 1;
  Gw = Gw - 1;
  int ans = -1;

  now_h = Sh;
  now_w = Sw;

  vector<vector<int>> maze;
  vector<int> v(W);

  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      std::cin >> cell;
      if (cell == '#') {
        // # = 1は壁
        v[j] = 1;
      } else {
        v[j] = 0;
      }
    }
    maze.push_back(v);
  }
  // ここまでインプット
  // どっちから来たかマーカーは0,1,2,3 = 上, 下, 左, 右, 上テレポ...

  // 最初だけ
  temp_v = {now_h, now_w, 0, 0};
  q_maze.push_front(temp_v);
  maze[now_h][now_w] = 1;

  while (q_maze.size() != 0) {
    // 左の状態を取得
    now_v = q_maze[0];
    // for(int i = 0; i < 4; i++){
    //      std::cout << now_v[i] << " ";
    // }
    // std::cout << "\\n";
    q_maze.pop_front();
    // goal判定
    if (now_v[0] == Gh && now_v[1] == Gw) {
      if (now_v[3] > ans) {
        ans = now_v[3];
        break;
      }
    } else if (now_v[2] == 1 && maze[now_v[0]][now_v[1]] == 1) {
      // テレポで来たけど既にコス0で来られていた場合何もしない
      //  std::cout << "bug" << now_h << " " << now_w << " " <<
      //  maze[now_h][now_w] << "\\n";
    } else {
      // ゴールに行ったら派生しない
      now_h = now_v[0];
      now_w = now_v[1];

      for (int i = -2; i <= 2; i++) {
        for (int j = -2; j <= 2; j++) {
          if (i != 0 || j != 0) {
            // 自分の立ち位置はさすがにだめ
            judge = judge_ikeru(now_h + i, now_w + j, maze);
            if (judge == 1) {
              // 端っこじゃなければさらに判定
              if (labs((long long)i) + labs((long long)j) == 1) {
                // コス0移動の場合
                if (maze[now_h + i][now_w + j] != 1) {
                  maze[now_h + i][now_w + j] = 1;
                  temp_v = {now_h + i, now_w + j, 0, now_v[3]};
                  q_maze.push_front(temp_v);
                }
              } else {
                // テレポ移動の場合
                if (maze[now_h + i][now_w + j] == 0) {
                  maze[now_h + i][now_w + j] = 2;
                  temp_v = {now_h + i, now_w + j, 1, now_v[3] + 1};
                  q_maze.push_back(temp_v);
                }
              }
            }
          }
        }
      }

      count++;
    }

    if (count > 2 * W * H) {
      break;
    }
  }

  if (ans == W * H) {
    std::cout << -1;
  } else {
    std::cout << ans;
  }
}

int judge_ikeru(int h, int w, vector<vector<int>> maze) {
  int ans = 1;
  int max_h = maze.size() - 1;
  int max_w = maze[0].size() - 1;

  if (h < 0 || h > max_h || w < 0 || w > max_w) {
    ans = 0;
  }
  return ans;
}