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

#include <algorithm>
#include <bitset>
#include <cmath>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <vector>
#define ll long long
using namespace std;
const long long INF = 1LL << 61;

// 状態が必要なときはこのPに複数の状態を入れておく
typedef pair<ll, ll> P;

// 入力
ll N, M;
ll sx, sy; // start地点の座標
ll gx, gy; // goal地点の座標
// ll d[MAX_N][MAX_M];
ll d[1000][1000];
char maze[1000][1000];
// 移動さきの四方向のベクトル
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};

// 移動さきの四方向のベクトル
int ldx[20] = {
    -2, -1, 0, 1, 2, -2, -1, 1, 2, -2, 2, -2, -1, 1, 2, -2, -1, 0, 1, 2,
};
int ldy[20] = {
    -2, -2, -2, -2, -2, -1, -1, -1, -1, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2,
};

void printD() {
  cout << "--------------------------------" << endl;
  for (ll i = 0; i < N; i++) {
    for (ll j = 0; j < M; j++) {
      if (d[i][j] != INF) {
        cout << d[i][j] << " ";
      } else {
        cout << "-1"
             << " ";
      }
    }
    cout << endl;
  }
  cout << "--------------------------------" << endl;
}
queue<P> stock;

ll depth = 0;

ll bfs() {
  queue<P> que;
  // スタート地点をqueに入れてその点の距離を0にする
  que.push(P(sx, sy));
  stock.push(P(sx, sy));
  d[sx][sy] = depth;
  while (que.size()) {
    P p = que.front();
    que.pop();
    // 取り出してきた位置がゴールならば探索をやめる
    if (p.first == gx && p.second == gy) {
      break;
    }
    // 四方向をループ
    for (int i = 0; i < 4; i++) {
      ll nx = p.first + dx[i];
      ll ny = p.second + dy[i];

      // 移動が可能かとすでに訪れたことがあるかの判定
      if (0 <= nx && nx < N && 0 <= ny && ny < M && maze[nx][ny] != '#' &&
          d[nx][ny] == INF) {
        // 移動できるのであればqueに入れてその点からの距離をpからの距離+1で確定する
        que.push(P(nx, ny));
        stock.push(P(nx, ny));

        d[nx][ny] = depth;
      }
    }
  }
  return d[gx][gy];
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cin >> N >> M;
  cin >> sx >> sy;
  cin >> gx >> gy;
  sy--;
  sx--;
  gy--;
  gx--;
  for (ll i = 0; i < N; i++) {
    for (ll j = 0; j < M; j++) {
      cin >> maze[i][j];
    }
  }
  for (ll i = 0; i < N; i++) {
    for (ll j = 0; j < M; j++) {
      d[i][j] = INF;
    }
  }
  queue<P> next;
  // bfsをする
  ll res = bfs();
  while (1) {
    // 0の位置を探す
    depth++;
    if (stock.size() == 0) {
      break;
    }
    while (stock.size()) {
      P p = stock.front();
      stock.pop();
      // 四方向をループ
      for (int i = 0; i < 20; i++) {
        ll nx = p.first + ldx[i];
        ll ny = p.second + ldy[i];

        // 移動が可能かとすでに訪れたことがあるかの判定
        if (0 <= nx && nx < N && 0 <= ny && ny < M && maze[nx][ny] != '#' &&
            d[nx][ny] == INF) {
          // 移動できるのであればqueに入れてその点からの距離をpからの距離+1で確定する
          next.push(P(nx, ny));
          d[nx][ny] = depth;
        }
      }
    }
    if (next.size() == 0) {
      break;
    }
    while (next.size()) {
      P p = next.front();
      next.pop();
      sx = p.first;
      sy = p.second;
      ll result = bfs();
    }
  }
  ll ans = d[gx][gy];
  if (d[gx][gy] != INF) {
    cout << d[gx][gy] << endl;
  } else {
    cout << -1 << endl;
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cmath>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <vector>
#define ll long long
using namespace std;
const long long INF = 1LL << 61;

// 状態が必要なときはこのPに複数の状態を入れておく
typedef pair<ll, ll> P;

// 入力
ll N, M;
ll sx, sy; // start地点の座標
ll gx, gy; // goal地点の座標
// ll d[MAX_N][MAX_M];
ll d[1000][1000];
char maze[1000][1000];
// 移動さきの四方向のベクトル
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};

// 移動さきの四方向のベクトル
int ldx[20] = {
    -2, -1, 0, 1, 2, -2, -1, 1, 2, -2, 2, -2, -1, 1, 2, -2, -1, 0, 1, 2,
};
int ldy[20] = {
    -2, -2, -2, -2, -2, -1, -1, -1, -1, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2,
};

void printD() {
  cout << "--------------------------------" << endl;
  for (ll i = 0; i < N; i++) {
    for (ll j = 0; j < M; j++) {
      if (d[i][j] != INF) {
        cout << d[i][j] << " ";
      } else {
        cout << "-1"
             << " ";
      }
    }
    cout << endl;
  }
  cout << "--------------------------------" << endl;
}

ll depth = 0;

ll bfs() {
  queue<P> que;
  // スタート地点をqueに入れてその点の距離を0にする
  que.push(P(sx, sy));
  d[sx][sy] = depth;
  while (que.size()) {
    P p = que.front();
    que.pop();
    // 取り出してきた位置がゴールならば探索をやめる
    if (p.first == gx && p.second == gy) {
      break;
    }
    // 四方向をループ
    for (int i = 0; i < 4; i++) {
      ll nx = p.first + dx[i];
      ll ny = p.second + dy[i];

      // 移動が可能かとすでに訪れたことがあるかの判定
      if (0 <= nx && nx < N && 0 <= ny && ny < M && maze[nx][ny] != '#' &&
          d[nx][ny] == INF) {
        // 移動できるのであればqueに入れてその点からの距離をpからの距離+1で確定する
        que.push(P(nx, ny));
        d[nx][ny] = depth;
      }
    }
  }
  return d[gx][gy];
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cin >> N >> M;
  cin >> sx >> sy;
  cin >> gx >> gy;
  sy--;
  sx--;
  gy--;
  gx--;
  for (ll i = 0; i < N; i++) {
    for (ll j = 0; j < M; j++) {
      cin >> maze[i][j];
    }
  }
  for (ll i = 0; i < N; i++) {
    for (ll j = 0; j < M; j++) {
      d[i][j] = INF;
    }
  }
  queue<P> stock;
  queue<P> next;
  // bfsをする
  ll res = bfs();
  while (1) {
    // 0の位置を探す
    for (ll i = 0; i < N; i++) {
      for (ll j = 0; j < M; j++) {
        if (d[i][j] == depth) {
          stock.push(P(i, j));
        }
      }
    }
    depth++;
    if (stock.size() == 0) {
      break;
    }
    while (stock.size()) {
      P p = stock.front();
      stock.pop();
      // 四方向をループ
      for (int i = 0; i < 20; i++) {
        ll nx = p.first + ldx[i];
        ll ny = p.second + ldy[i];

        // 移動が可能かとすでに訪れたことがあるかの判定
        if (0 <= nx && nx < N && 0 <= ny && ny < M && maze[nx][ny] != '#' &&
            d[nx][ny] == INF) {
          // 移動できるのであればqueに入れてその点からの距離をpからの距離+1で確定する
          next.push(P(nx, ny));
          d[nx][ny] = depth;
        }
      }
    }
    if (next.size() == 0) {
      break;
    }
    while (next.size()) {
      P p = next.front();
      next.pop();
      sx = p.first;
      sy = p.second;
      ll result = bfs();
    }
  }
  ll ans = d[gx][gy];
  if (d[gx][gy] != INF) {
    cout << d[gx][gy] << endl;
  } else {
    cout << -1 << endl;
  }
}