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

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

// 型定義
typedef long long ll;
typedef pair<ll, ll> P;

// forループ
#define REP(i, n) for (ll i = 0; i < (ll)(n); ++i)

// 定数宣言
const int INF = 1e9;
const int MOD = 1e9 + 7;
const ll LINF = 1e18;

// グラフ表現
using Graph = vector<vector<int>>;

// グラフの辺表現
using Edge = map<pair<int, int>, int>;

// n次元配列の初期化。第２引数の型のサイズごとに初期化していく。
template <typename A, size_t N, typename T>
void Fill(A (&array)[N], const T &val) {
  std::fill((T *)array, (T *)(array + N), val);
}

// 最大公約数
ll gcd(ll a, ll b) {
  if (a % b == 0)
    return (b);
  else
    return (gcd(b, a % b));
}

// 最小公倍数
ll lcm(ll a, ll b) { return a * b / gcd(a, b); }

int main() {
  cout << fixed << setprecision(15);
  ll H, W, K;
  cin >> H >> W >> K;

  ll x1, y1, x2, y2;
  cin >> x1 >> y1 >> x2 >> y2;

  vector<vector<char>> c;
  vector<vector<ll>> v;
  c.assign(H, vector<char>(W, '.'));
  v.assign(H, vector<ll>(W, INF));

  REP(i, H) {
    string S;
    cin >> S;

    REP(j, W) { c[i][j] = S[j]; }
  }

  // indexが0からなので1減らす
  x1--;
  y1--;
  x2--;
  y2--;

  vector<vector<ll>> dx(4, vector<ll>(K));
  vector<vector<ll>> dy(4, vector<ll>(K));

  for (ll i = 0; i < K; i++) {
    dx[0][i] = i + 1;
    dy[0][i] = 0;
  }
  for (ll i = 0; i < K; i++) {
    dx[1][i] = (i + 1) * (-1);
    dy[1][i] = 0;
  }
  for (ll i = 0; i < K; i++) {
    dx[2][i] = 0;
    dy[2][i] = i + 1;
  }
  for (ll i = 0; i < K; i++) {
    dx[3][i] = 0;
    dy[3][i] = (i + 1) * (-1);
  }

  // REP(i, 4){
  //     // 4方向へ繰り返す
  //     REP(j, K) {
  //         cout << dx[i][j] << " " << dy[i][j] << endl;
  //     }
  // }

  // キューを準備
  queue<P> que;
  // 探索の初期値を入れる
  que.push(P(x1, y1));
  v[x1][y1] = 0;

  while (true) {
    // 　もしも探索地点がゴールならば現在の歩数を探索終了
    if (que.empty()) {
      break;
    }
    // キューの中身を取り出す
    P p = que.front();
    que.pop();
    int x = p.first;
    int y = p.second;
    int s = v[x][y];

    // cout << "x:" << x << " y:" << y << endl;
    // cout << c[0][1] << endl;

    REP(i, 4) {
      // 4方向へ繰り返す
      REP(j, K) {
        int nx = x + dx[i][j];
        int ny = y + dy[i][j];

        // 移動すると範囲外になったり、#だったり、探索済みだったら終了する
        if (nx < 0 || nx >= H || ny < 0 || ny >= W) {
          // i = (i/K + 1)*K-1;
          break;
        }
        // if(v[nx][ny] != -1 || c[nx][ny] == '@'){
        //     break;
        // }
        if (c[nx][ny] == '@') {
          break;
        }
        if (v[nx][ny] <= v[x][y]) {
          break;
        }
        // if(v[nx][ny] != -1){
        //     continue;
        // }
        // 未探索だったら、キューに入れて現在の距離を記録
        if (v[nx][ny] == INF) {
          que.push(P(nx, ny));
          v[nx][ny] = s + 1;
        }
      }
    }
  }

  if (v[x2][y2] == INF) {
    v[x2][y2] = -1;
  }
  cout << v[x2][y2] << endl;
  return 0;
}

Error: TLE

Fixed submission:

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

// 型定義
typedef long long ll;
typedef pair<ll, ll> P;

// forループ
#define REP(i, n) for (ll i = 0; i < (ll)(n); ++i)

// 定数宣言
const int INF = 1e9;
const int MOD = 1e9 + 7;
const ll LINF = 1e18;

// グラフ表現
using Graph = vector<vector<int>>;

// グラフの辺表現
using Edge = map<pair<int, int>, int>;

// n次元配列の初期化。第２引数の型のサイズごとに初期化していく。
template <typename A, size_t N, typename T>
void Fill(A (&array)[N], const T &val) {
  std::fill((T *)array, (T *)(array + N), val);
}

// 最大公約数
ll gcd(ll a, ll b) {
  if (a % b == 0)
    return (b);
  else
    return (gcd(b, a % b));
}

// 最小公倍数
ll lcm(ll a, ll b) { return a * b / gcd(a, b); }

int main() {
  cout << fixed << setprecision(15);
  ll H, W, K;
  cin >> H >> W >> K;

  ll x1, y1, x2, y2;
  cin >> x1 >> y1 >> x2 >> y2;

  vector<vector<char>> c;
  vector<vector<ll>> v;
  c.assign(H, vector<char>(W, '.'));
  v.assign(H, vector<ll>(W, -1));

  REP(i, H) {
    string S;
    cin >> S;

    REP(j, W) { c[i][j] = S[j]; }
  }

  // indexが0からなので1減らす
  x1--;
  y1--;
  x2--;
  y2--;

  vector<vector<ll>> dx(4, vector<ll>(K));
  vector<vector<ll>> dy(4, vector<ll>(K));

  for (ll i = 0; i < K; i++) {
    dx[0][i] = i + 1;
    dy[0][i] = 0;
  }
  for (ll i = 0; i < K; i++) {
    dx[1][i] = (i + 1) * (-1);
    dy[1][i] = 0;
  }
  for (ll i = 0; i < K; i++) {
    dx[2][i] = 0;
    dy[2][i] = i + 1;
  }
  for (ll i = 0; i < K; i++) {
    dx[3][i] = 0;
    dy[3][i] = (i + 1) * (-1);
  }

  // REP(i, 4){
  //     // 4方向へ繰り返す
  //     REP(j, K) {
  //         cout << dx[i][j] << " " << dy[i][j] << endl;
  //     }
  // }

  // キューを準備
  queue<P> que;
  // 探索の初期値を入れる
  que.push(P(x1, y1));
  v[x1][y1] = 0;

  while (true) {
    // 　もしも探索地点がゴールならば現在の歩数を探索終了
    if (que.empty()) {
      break;
    }
    // キューの中身を取り出す
    P p = que.front();
    que.pop();
    int x = p.first;
    int y = p.second;
    int s = v[x][y];

    // cout << "x:" << x << " y:" << y << endl;
    // cout << c[0][1] << endl;

    REP(i, 4) {
      // 4方向へ繰り返す
      REP(j, K) {
        int nx = x + dx[i][j];
        int ny = y + dy[i][j];

        // 移動すると範囲外になったり、#だったり、探索済みだったら終了する
        if (nx < 0 || nx >= H || ny < 0 || ny >= W) {
          // i = (i/K + 1)*K-1;
          break;
        }
        // if(v[nx][ny] != -1 || c[nx][ny] == '@'){
        //     break;
        // }
        if (c[nx][ny] == '@') {
          break;
        }
        if (v[nx][ny] != -1) {
          continue;
        }
        if (v[nx][ny] >= s) {
          break;
        }
        // 未探索だったら、キューに入れて現在の距離を記録
        que.push(P(nx, ny));
        v[nx][ny] = s + 1;
      }
    }
  }

  cout << v[x2][y2] << endl;
  return 0;
}