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

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
using vi = vector<int>;
using vv = vector<vi>;
using vvv = vector<vv>;
using P = pair<int, int>;
using vP = vector<P>;
using vvP = vector<vP>;
using vvvP = vector<vvP>;
using t3 = tuple<int, int, int>;

const int INF = 1001001001;

int main() {
  int h, w, k;
  cin >> h >> w >> k;

  int x1, y1, x2, y2;
  cin >> x1 >> y1 >> x2 >> y2;
  x1--;
  y1--;
  x2--;
  y2--;

  vector<string> s(h);
  rep(i, h) cin >> s[i];

  vvv cost(h, vv(w, vi(4, INF)));
  vvv used(h, vv(w, vi(4, 0)));
  priority_queue<P, vector<P>, greater<P>> q;

  rep(i, 4) {
    cost[x1][y1][i] = 0;
    used[x1][y1][i] = 0;
    q.push(P(0, (x1 * w + y1) * 4 + i)); // 始点, 全方位
  }

  vector<int> dx = {0, 1, 0, -1};
  vector<int> dy = {1, 0, -1, 0};

  while (!q.empty()) {
    int c = q.top().first;  // コスト
    int p = q.top().second; // 場所,方向
    int go = c % k;         // その方向に何マス直進してきたか
    c /= k;

    int px = p / (4 * w); // x座標
    int py = (p / 4) % w; // y座標
    int d = p % 4;        // 方向
    q.pop();

    if (used[px][py][d])
      continue;
    used[px][py][d] = 1;

    // if(c*k+go>cost[px][py][d])continue;
    cost[px][py][d] = c * k + go;

    // 左右に向きを変える遷移
    if (!used[px][py][(d + 1) % 4])
      q.push(
          P(((c * k + go + k - 1) / k) * k, (px * w + py) * 4 + (d + 1) % 4));
    if (!used[px][py][(d + 3) % 4])
      q.push(
          P(((c * k + go + k - 1) / k) * k, (px * w + py) * 4 + (d + 3) % 4));

    // 直進する遷移
    int nx = px + dx[d];
    int ny = py + dy[d];
    if (nx < 0 || ny < 0 || nx >= h || ny >= w)
      continue;
    if (s[nx][ny] == '@')
      continue;

    if (!used[nx][ny][d])
      q.push(P(c * k + go + 1, (nx * w + ny) * 4 + d));
  }

  int ans = INF;

  rep(i, 4) ans = min(ans, cost[x2][y2][i]);
  cout << (ans == INF ? -1 : (ans + k - 1) / k) << endl;
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
using vi = vector<int>;
using vv = vector<vi>;
using vvv = vector<vv>;
using P = pair<int, int>; //(cost,(to, dir))
const int INF = 1001001001;

int main() {
  int h, w, k;
  cin >> h >> w >> k;

  int x1, y1, x2, y2;
  cin >> x1 >> y1 >> x2 >> y2;
  x1--;
  y1--;
  x2--;
  y2--;

  vector<string> s(h);
  rep(i, h) cin >> s[i];

  vvv cost(h, vv(w, vi(4, INF)));

  rep(i, 4) cost[x1][y1][i] = 0;
  vvv used(h, vv(w, vi(4, 0)));

  priority_queue<P, vector<P>, greater<P>> q;
  rep(i, 4) {
    q.push(P(0, (x1 * w + y1) * 4 + i)); // 始点, 全方位
  }

  vector<int> dx = {0, 1, 0, -1};
  vector<int> dy = {1, 0, -1, 0};

  while (!q.empty()) {
    int c = q.top().first;
    int p = q.top().second;
    int px = p / (4 * w);
    int py = (p / 4) % w;
    int d = p % 4;
    q.pop();
    if (used[px][py][d])
      continue;
    if (c > cost[px][py][d])
      continue;
    cost[px][py][d] = c;
    used[px][py][d] = 1;
    // 後戻りしない
    // さらにk未満なら前進しない
    //@なら終了
    for (int i = 1; i <= k; i++) {
      int nx = px + dx[d] * i;
      int ny = py + dy[d] * i;
      if (nx < 0 || ny < 0 || nx >= h || ny >= w)
        break;
      if (s[nx][ny] == '@')
        break;
      if (!used[nx][ny][(d + 1) % 4])
        q.push(P(c + 1, (nx * w + ny) * 4 + (d + 1) % 4));
      if (!used[nx][ny][(d + 3) % 4])
        q.push(P(c + 1, (nx * w + ny) * 4 + (d + 3) % 4));
      if (i == k && !used[nx][ny][d])
        q.push(P(c + 1, (nx * w + ny) * 4 + d));
    }
  }
  int ans = INF;
  rep(i, 4) ans = min(ans, cost[x2][y2][i]);
  cout << (ans == INF ? -1 : ans) << endl;
  return 0;
}