Problem p02644 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <bitset>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> P;
typedef pair<ll, P> P1;
typedef pair<P, P> P2;
#define pu push
#define pb push_back
#define mp make_pair
#define eps 1e-7
#define INF 1000000000
#define fi first
#define sc second
#define rep(i, x) for (ll i = 0; i < x; i++)
#define repn(i, x) for (ll i = 1; i <= x; i++)
#define SORT(x) sort(x.begin(), x.end())
#define ERASE(x) x.erase(unique(x.begin(), x.end()), x.end())
#define POSL(x, v) (lower_bound(x.begin(), x.end(), v) - x.begin())
#define POSU(x, v) (upper_bound(x.begin(), x.end(), v) - x.begin())

const int MAX = 510000;
const int MOD = 1000000007;

// 四方向への移動ベクトル
const ll dx[4] = {1, 0, -1, 0};
const ll dy[4] = {0, 1, 0, -1};

int main() {
  ll H, W, K;
  cin >> H >> W >> K;
  ll sx, sy, gx, gy;
  cin >> sx >> sy >> gx >> gy;
  sx--;
  sy--;
  gx--;
  gy--;
  vector<string> field(H);
  rep(i, H) cin >> field[i];

  // 各セルの最短距離 (訪れていないところは -1 としておく)
  vector<vector<int>> d(H, vector<int>(W, -1));
  d[sx][sy] = 0; // スタートを 0 に

  // そもそもいけない時はKでの探索しない
  queue<P> que1;
  que1.pu(mp(sx, sy));
  while (!que1.empty()) {
    pair<ll, ll> current_pos =
        que1.front(); // キューの先頭を見る (C++ ではこれをしても pop しない)
    ll x = current_pos.first;
    ll y = current_pos.second;
    que1.pop(); // キューから pop を忘れずに

    // 隣接頂点を探索
    for (ll direction = 0; direction < 4; ++direction) {
      ll next_x = x + dx[direction];
      ll next_y = y + dy[direction];
      if (next_x < 0 || next_x >= H || next_y < 0 || next_y >= W)
        continue; // 場外アウトならダメ
      if (field[next_x][next_y] == '@')
        continue; // 壁はダメ

      // まだ見ていない頂点なら push
      if (d[next_x][next_y] == -1) {
        que1.push(make_pair(next_x, next_y));
        d[next_x][next_y] = d[x][y] + 1; // (next_x, next_y) の距離も更新
      }
    }
  }
  if (d[gx][gy] == -1) {
    cout << -1 << endl;
    return 0;
  }

  // 各セルの最短距離 (訪れていないところは -1 としておく)
  vector<vector<int>> dist(H, vector<int>(W, -1));
  dist[sx][sy] = 0; // スタートを 0 に

  queue<P> que;
  que.pu(mp(sx, sy));
  while (!que.empty()) {
    pair<ll, ll> current_pos =
        que.front(); // キューの先頭を見る (C++ ではこれをしても pop しない)
    ll x = current_pos.first;
    ll y = current_pos.second;
    if (dist[x][y] > d[gx][gy])
      break;
    que.pop(); // キューから pop を忘れずに

    // 隣接頂点を探索
    for (ll direction = 0; direction < 4; ++direction) {
      repn(j, K) {
        ll next_x = x + j * dx[direction];
        ll next_y = y + j * dy[direction];
        if (next_x < 0 || next_x >= H || next_y < 0 || next_y >= W)
          break; // 場外アウトならダメ
        if (field[next_x][next_y] == '@')
          break; // 壁はダメ

        if (dist[next_x][next_y] > dist[x][y] + 1)
          break;
        if (dist[next_x][next_y] < dist[x][y]) {
          if (dist[next_x][next_y] != -1) {
            break;
          }
        }

        // まだ見ていない頂点なら push
        if (dist[next_x][next_y] == -1) {
          que.push(make_pair(next_x, next_y));
          dist[next_x][next_y] =
              dist[x][y] + 1; // (next_x, next_y) の距離も更新
        }
      }
    }
  }
  /*
  rep(i,H){
    rep(j,W){
      cout << dist[i][j] << " ";
    }
    cout << endl;
  }
  */
  cout << dist[gx][gy] << endl;
}


Fixed submission:
#include <algorithm>
#include <bitset>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> P;
typedef pair<ll, P> P1;
typedef pair<P, P> P2;
#define pu push
#define pb push_back
#define mp make_pair
#define eps 1e-7
#define INF 1000000000
#define fi first
#define sc second
#define rep(i, x) for (ll i = 0; i < x; i++)
#define repn(i, x) for (ll i = 1; i <= x; i++)
#define SORT(x) sort(x.begin(), x.end())
#define ERASE(x) x.erase(unique(x.begin(), x.end()), x.end())
#define POSL(x, v) (lower_bound(x.begin(), x.end(), v) - x.begin())
#define POSU(x, v) (upper_bound(x.begin(), x.end(), v) - x.begin())

const int MAX = 510000;
const int MOD = 1000000007;

// 四方向への移動ベクトル
const ll dx[4] = {1, 0, -1, 0};
const ll dy[4] = {0, 1, 0, -1};

int main() {
  ll H, W, K;
  cin >> H >> W >> K;
  ll sx, sy, gx, gy;
  cin >> sx >> sy >> gx >> gy;
  sx--;
  sy--;
  gx--;
  gy--;
  vector<string> field(H);
  rep(i, H) cin >> field[i];

  // 各セルの最短距離 (訪れていないところは -1 としておく)
  vector<vector<int>> d(H, vector<int>(W, -1));
  d[sx][sy] = 0; // スタートを 0 に

  // そもそもいけない時はKでの探索しない
  queue<P> que1;
  que1.pu(mp(sx, sy));
  while (!que1.empty()) {
    pair<ll, ll> current_pos =
        que1.front(); // キューの先頭を見る (C++ ではこれをしても pop しない)
    ll x = current_pos.first;
    ll y = current_pos.second;
    que1.pop(); // キューから pop を忘れずに

    // 隣接頂点を探索
    for (ll direction = 0; direction < 4; ++direction) {
      ll next_x = x + dx[direction];
      ll next_y = y + dy[direction];
      if (next_x < 0 || next_x >= H || next_y < 0 || next_y >= W)
        continue; // 場外アウトならダメ
      if (field[next_x][next_y] == '@')
        continue; // 壁はダメ

      // まだ見ていない頂点なら push
      if (d[next_x][next_y] == -1) {
        que1.push(make_pair(next_x, next_y));
        d[next_x][next_y] = d[x][y] + 1; // (next_x, next_y) の距離も更新
      }
    }
  }
  if (d[gx][gy] == -1) {
    cout << -1 << endl;
    return 0;
  }

  // 各セルの最短距離 (訪れていないところは -1 としておく)
  vector<vector<int>> dist(H, vector<int>(W, -1));
  dist[sx][sy] = 0; // スタートを 0 に

  queue<P> que;
  que.pu(mp(sx, sy));
  while (!que.empty()) {
    pair<ll, ll> current_pos =
        que.front(); // キューの先頭を見る (C++ ではこれをしても pop しない)
    ll x = current_pos.first;
    ll y = current_pos.second;
    if (dist[x][y] > d[gx][gy])
      break;
    que.pop(); // キューから pop を忘れずに

    // 隣接頂点を探索
    for (ll direction = 0; direction < 4; ++direction) {
      repn(j, K) {
        ll next_x = x + j * dx[direction];
        ll next_y = y + j * dy[direction];
        if (next_x < 0 || next_x >= H || next_y < 0 || next_y >= W)
          break; // 場外アウトならダメ
        if (field[next_x][next_y] == '@')
          break; // 壁はダメ

        if (dist[next_x][next_y] > dist[x][y] + 1)
          break;
        if (dist[next_x][next_y] <= dist[x][y]) {
          if (dist[next_x][next_y] != -1) {
            break;
          }
        }

        // まだ見ていない頂点なら push
        if (dist[next_x][next_y] == -1) {
          que.push(make_pair(next_x, next_y));
          dist[next_x][next_y] =
              dist[x][y] + 1; // (next_x, next_y) の距離も更新
        }
      }
    }
  }
  /*
  rep(i,H){
    rep(j,W){
      cout << dist[i][j] << " ";
    }
    cout << endl;
  }
  */
  cout << dist[gx][gy] << endl;
}