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

#include <algorithm>
#include <cassert>
#include <cstdio>
#include <iostream>
#include <numeric>
#include <queue>
#include <string>
#include <tuple>
#include <utility>
#include <vector>

using namespace std;

using PII = pair<int, int>;
using TUP = tuple<int, int, int, int>;
using VL = vector<long long>;
using VVL = vector<VL>;
using VVVL = vector<VVL>;

const long long inf = 1e18;

const vector<int> dc = {1, 0, -1, 0};
const vector<int> dr = {0, 1, 0, -1};

int main() {
  int h, w, k;
  int sx, sy, gx, gy;
  cin >> h >> w >> k;
  cin >> sx >> sy >> gx >> gy;
  sx--;
  sy--;
  gx--;
  gy--;

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

  grid[sx][sy] = 'S';
  grid[gx][gy] = 'G';

  // printf("hwk %d %d %d\\n", h, w, k);
  // for (auto s: grid) {
  // 	cout << s << endl;
  // }

  VVVL dist(4, VVL(h, VL(w, inf)));
  priority_queue<TUP, vector<TUP>, greater<TUP>> que; // cost, dir, row, col

  auto push = [&](long long cost, int dir, int row, int col) {
    if (row < 0 || h <= row || col < 0 || w <= col) {
      return;
    }
    if (grid[row][col] == '@') {
      return;
    }

    if (cost < dist[dir][row][col]) {
      que.emplace(cost, dir, row, col);
      dist[dir][row][col] = cost;
    }
  };

  for (int i = 0; i < 4; i++) {
    push(0, i, sx, sy);
  }

  int dir, r, c;
  long long cost;
  while (!que.empty()) {
    tie(cost, dir, r, c) = que.top();
    que.pop();

    if (cost != dist[dir][r][c]) {
      continue;
    }

    if (grid[r][c] == 'G') {
      break;
    }

    for (int dir2 = 0; dir2 < 4; dir2++) {
      long long cost2 = (cost + k - 1) / k * k;
      push(cost2, dir2, r, c);
    }
    push(cost + 1, dir, r + dr[dir], c + dc[dir]);
  }

  long long ans = inf;
  for (int i = 0; i < 4; i++) {
    ans = min(ans, dist[i][gx][gy]);
  }
  if (ans == inf) {
    cout << -1 << endl;
  } else {
    ans = (ans + k - 1) / k;
    cout << ans << endl;
  }

  return 0;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cstdio>
#include <iostream>
#include <numeric>
#include <queue>
#include <string>
#include <tuple>
#include <utility>
#include <vector>

using namespace std;

using PII = pair<int, int>;
using TUP = tuple<int, int, int>;

const int inf = 1e9;

void show(vector<vector<int>> &vv) {
  printf("-------\\n");
  for (auto v : vv) {
    for (auto x : v) {
      if (x == inf) {
        // printf(" inf");
        printf(" --");
      } else {
        printf(" %2d", x);
      }
    }
    printf("\\n");
  }
}

void show(vector<vector<int>> &vv, int r1, int r2, int c1, int c2) {
  printf("-------\\n");
  assert(0 <= r1 && r1 < r2 && r2 < vv.size());
  assert(0 <= c1 && c1 < c2 && c2 < vv[0].size());
  for (int i = r1; i <= r2; i++) {
    for (int j = c1; j <= c2; j++) {
      if (vv[i][j] == inf) {
        // printf(" inf");
        printf(" --");
      } else {
        // printf(" %3d", vv[i][j]);
        printf(" %2d", vv[i][j]);
      }
    }
    printf("\\n");
  }
}

int main() {
  int h, w, k;
  int sx, sy, gx, gy;
  cin >> h >> w >> k;
  cin >> sx >> sy >> gx >> gy;
  sx--;
  sy--;
  gx--;
  gy--;

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

  grid[sx][sy] = 'S';
  grid[gx][gy] = 'G';

  vector<vector<int>> dist(h, vector<int>(w, inf));

  priority_queue<TUP, vector<TUP>, greater<TUP>> que; // walk, row, col
  que.emplace(0, sx, sy);

  int walk, r, c;
  auto push = [&](int walk, int row, int col) {
    if (row < 0 || h <= row || col < 0 || w <= col) {
      return false;
    }
    if (grid[row][col] == '@' || walk >= dist[row][col]) {
      return false;
    }
    que.emplace(walk + 1, row, col);
    dist[row][col] = walk + 1;
    return true;
  };

  while (!que.empty()) {
    tie(walk, r, c) = que.top();
    que.pop();

    if (walk > dist[r][c]) {
      continue;
    }
    dist[r][c] = walk;
    if (grid[r][c] == 'G') {
      break;
    }

    for (int i = 1; i <= k; i++) {
      auto to_next = push(walk, r + i, c);
      if (!to_next) {
        break;
      }
    }
    for (int i = 1; i <= k; i++) {
      auto to_next = push(walk, r - i, c);
      if (!to_next) {
        break;
      }
    }

    for (int i = 1; i <= k; i++) {
      auto to_next = push(walk, r, c + i);
      if (!to_next) {
        break;
      }
    }
    for (int i = 1; i <= k; i++) {
      auto to_next = push(walk, r, c - i);
      if (!to_next) {
        break;
      }
    }
  }

  int ans = dist[gx][gy] == inf ? -1 : dist[gx][gy];
  cout << ans << endl;
  // show(dist);
  return 0;
}