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

#include <bits/stdc++.h>

using namespace std;

using ll = long long;

constexpr char newl = '\\n';
constexpr int INF = 1e9;
constexpr int dh[] = {1, 0, -1, 0};
constexpr int dw[] = {0, 1, 0, -1};

constexpr double ticks_per_sec = 2800000000;
constexpr double ticks_per_sec_inv = 1.0 / ticks_per_sec;
inline double rdtsc() { // in seconds
  uint32_t lo, hi;
  asm volatile("rdtsc" : "=a"(lo), "=d"(hi));
  return (((uint64_t)hi << 32) | lo) * ticks_per_sec_inv;
}
constexpr double TLE = 3; // sec
constexpr double time_limit = TLE * 0.995;

int H, W;
int x2, y2, K;

struct State {
  int pos;
  int dir;
  int rest;
  int cost;
  bool rot;
  // ll es_cost;

  State(int ch, int cw, int di, int re, int co, bool r)
      : pos(ch * W + cw), dir(di), rest(re), cost(co), rot(r) {
    // es_cost = (abs(h - x2) + K - 1) / K + (abs(w - y2) + K - 1) / K;
  }

  bool operator>(const State &s) const {
    // if (es_cost != s.es_cost) return es_cost > s.es_cost;
    if (cost != s.cost)
      return cost > s.cost;
    return rest < s.rest;
  }
};

int main() {
  cin.tie(nullptr);
  ios::sync_with_stdio(false);
  // double clock_begin = rdtsc();

  cin >> H >> W >> K;

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

  vector<string> c(H);
  for (int i = 0; i < H; i++) {
    cin >> c[i];
  }

  vector<vector<vector<int>>> minc(4,
                                   vector<vector<int>>(H, vector<int>(W, INF)));
  vector<vector<vector<int>>> maxr(4,
                                   vector<vector<int>>(H, vector<int>(W, -1)));
  priority_queue<State, vector<State>, greater<State>> pq;
  for (int i = 0; i < 4; i++) {
    pq.emplace(x1, y1, i, K, 1, false);
    minc[i][x1][y1] = 1;
    maxr[i][x1][y1] = K;
  }

  while (!pq.empty()) {
    State cur = pq.top();
    pq.pop();
    int h = cur.pos / W, w = cur.pos % W;
    if (minc[cur.dir][h][w] < cur.cost)
      continue;
    if (minc[cur.dir][h][w] == cur.cost && maxr[cur.dir][h][w] > cur.rest)
      continue;

    if (h == x2 && w == y2)
      break;

    // cerr << cur.dir << " " << cur.h << " " << cur.w << " " <<
    // minc[cur.dir][cur.h][cur.w] << newl;

    while (true) {
      int nh = h + dh[cur.dir], nw = w + dw[cur.dir];
      if (nh < 0 || nh >= H || nw < 0 || nw >= W)
        break;
      if (c[nh][nw] == '@')
        break;

      int rest = (cur.rest > 0 ? cur.rest - 1 : K - 1);
      int cost = cur.cost + !(cur.rest > 0);

      if (minc[cur.dir][nh][nw] < cost)
        break;
      if (minc[cur.dir][nh][nw] == cost && maxr[cur.dir][nh][nw] > rest)
        break;

      minc[cur.dir][nh][nw] = cost;
      maxr[cur.dir][nh][nw] = rest;
      pq.emplace(nh, nw, cur.dir, rest, cost, false);
      break;
    }

    while (true) {
      int dir = (cur.dir + 1) % 4;
      int nh = h, nw = w;

      int rest = K;
      int cost = cur.cost + !cur.rot;

      if (minc[dir][nh][nw] < cost)
        break;
      if (minc[dir][nh][nw] == cost && maxr[dir][nh][nw] > rest)
        break;

      minc[dir][nh][nw] = cost;
      maxr[dir][nh][nw] = rest;
      pq.emplace(nh, nw, dir, rest, cost, true);

      break;
    }
  }

  int ans = INF;
  for (int i = 0; i < 4; i++) {
    ans = min(ans, minc[i][x2][y2]);
  }
  cout << (ans >= INF ? -1 : ans) << newl;
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

using ll = long long;

constexpr char newl = '\\n';
constexpr int INF = 1e9;
constexpr int dh[] = {1, 0, -1, 0};
constexpr int dw[] = {0, 1, 0, -1};

constexpr double ticks_per_sec = 2800000000;
constexpr double ticks_per_sec_inv = 1.0 / ticks_per_sec;
inline double rdtsc() { // in seconds
  uint32_t lo, hi;
  asm volatile("rdtsc" : "=a"(lo), "=d"(hi));
  return (((uint64_t)hi << 32) | lo) * ticks_per_sec_inv;
}
constexpr double TLE = 3; // sec
constexpr double time_limit = TLE * 0.995;

int H, W;
int x2, y2, K;

struct State {
  int pos;
  int dir;
  int rest;
  int cost;
  // ll es_cost;

  State(int ch, int cw, int di, int re, int co)
      : pos(ch * W + cw), dir(di), rest(re), cost(co) {
    // es_cost = (abs(h - x2) + K - 1) / K + (abs(w - y2) + K - 1) / K;
  }

  bool operator>(const State &s) const {
    // if (es_cost != s.es_cost) return es_cost > s.es_cost;
    if (cost != s.cost)
      return cost > s.cost;
    return rest < s.rest;
  }
};

int main() {
  cin.tie(nullptr);
  ios::sync_with_stdio(false);
  // double clock_begin = rdtsc();

  cin >> H >> W >> K;

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

  vector<string> c(H);
  for (int i = 0; i < H; i++) {
    cin >> c[i];
  }

  vector<vector<ll>> ans(H, vector<ll>(W, INF));
  vector<vector<vector<ll>>> minc(4, vector<vector<ll>>(H, vector<ll>(W, INF)));
  vector<vector<vector<int>>> maxr(4,
                                   vector<vector<int>>(H, vector<int>(W, -1)));
  priority_queue<State, vector<State>, greater<State>> pq;
  ans[x1][y1] = 1;
  for (int i = 0; i < 4; i++) {
    pq.emplace(x1, y1, i, K, 1);
    minc[i][x1][y1] = 1;
    maxr[i][x1][y1] = K;
  }

  while (!pq.empty()) {
    State cur = pq.top();
    pq.pop();
    int h = cur.pos / W, w = cur.pos % W;
    if (cur.cost > ans[h][w])
      continue;
    if (minc[cur.dir][h][w] < cur.cost)
      continue;
    if (minc[cur.dir][h][w] == cur.cost && maxr[cur.dir][h][w] > cur.rest)
      continue;

    // cerr << cur.dir << " " << cur.h << " " << cur.w << " " <<
    // minc[cur.dir][cur.h][cur.w] << newl;
    if (h == x2 && w == y2)
      break;

    int ban = (cur.dir + 2) % 4;
    for (int i = 0; i < 4; ++i) {
      if (i == ban)
        continue;

      int nh = h + dh[i], nw = w + dw[i];
      if (nh < 0 || nh >= H || nw < 0 || nw >= W)
        continue;
      if (c[nh][nw] == '@')
        continue;

      int rest = (cur.dir == i && cur.rest > 0 ? cur.rest - 1 : K - 1);
      ll cost = cur.cost + !(cur.dir == i && cur.rest > 0);

      if (cost > ans[nh][nw])
        continue;
      if (minc[i][nh][nw] < cost)
        continue;
      if (minc[i][nh][nw] == cost && maxr[i][nh][nw] > rest)
        continue;

      ans[nh][nw] = min(ans[nh][nw], cost);
      minc[i][nh][nw] = cost;
      maxr[i][nh][nw] = rest;
      pq.emplace(nh, nw, i, rest, cost);
    }
  }

  cout << (ans[x2][y2] >= INF ? -1 : ans[x2][y2]) << newl;
  return 0;
}