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

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

const long long INF = (long long)1e18;
const vector<int> dx = {1, -1, 0, 0};
const vector<int> dy = {0, 0, 1, -1};

struct heap_node {
  long long dist;
  int x, y, dir;
};

inline bool operator>(const heap_node &a, const heap_node &b) {
  return a.dist > b.dist;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int h, w, k;
  cin >> h >> w >> k;
  int x1, y1, x2, y2;
  cin >> x1 >> y1 >> x2 >> y2;
  x1--;
  y1--;
  x2--;
  y2--;
  vector<string> board(h);
  for (int i = 0; i < h; i++) {
    cin >> board[i];
  }

  auto to_int = [&](int x, int y, int dir) { return dir * h * w + w * x + y; };

  vector<long long> dist(4 * h * w, INF);
  priority_queue<heap_node, vector<heap_node>, greater<heap_node>> pq;
  for (int i = 0; i < 4; i++) {
    pq.push({0, x1, y1, i});
    dist[to_int(x1, y1, i)] = 0;
  }
  while (!pq.empty()) {
    long long d = pq.top().dist;
    int x = pq.top().x, y = pq.top().y, dir = pq.top().dir;
    pq.pop();
    if (d > dist[to_int(x, y, dir)]) {
      continue;
    }
    for (int i = 0; i < 4; i++) {
      if (dir == i) {
        int nx = x + dx[dir], ny = y + dy[dir];
        if (nx < 0 || nx >= h || ny < 0 || ny >= w || board[nx][ny] == '@') {
          continue;
        }
        if (d + 1 < dist[to_int(nx, ny, dir)]) {
          dist[to_int(nx, ny, dir)] = d + 1;
          pq.push({dist[to_int(nx, ny, dir)], nx, ny, dir});
        }
      } else {
        if ((d + k - 1) / k * k < dist[to_int(x, y, i)]) {
          dist[to_int(x, y, i)] = (d + k - 1) / k * k;
          pq.push({dist[to_int(x, y, i)], x, y, i});
        }
      }
    }
  }
  long long ans = INF;
  for (int i = 0; i < 4; i++) {
    if (dist[to_int(x2, y2, i)] != INF) {
      ans = min(ans, (dist[to_int(x2, y2, i)] + k - 1) / k);
    }
  }
  if (ans == INF) {
    cout << -1 << '\\n';
    return 0;
  }
  cout << ans << '\\n';
  return 0;
}

Error: TLE

Fixed submission:

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

const int INF = 0x3f3f3f3f;

int h, w, k;
int x2, y2;
vector<string> grid;
vector<vector<int>> dist;

int horizontal(int x, int y);
int vertical(int x, int y);

int vertical(int x, int y) {
  // cout << "v " << x << ' ' << y << endl;
  if (x == x2 && y == y2) {
    return 0;
  }
  int ans = INF;
  for (int j = x + 1; j < h && grid[j][y] == '.'; j++) {
    if (dist[j][y] > dist[x][y] + (j - x + k - 1) / k) {
      dist[j][y] = dist[x][y] + (j - x + k - 1) / k;
      ans = min(ans, horizontal(j, y) + (j - x + k - 1) / k);
    }
  }
  for (int j = x - 1; j >= 0 && grid[j][y] == '.'; j--) {
    if (dist[j][y] > dist[x][y] + (x - j + k - 1) / k) {
      dist[j][y] = dist[x][y] + (x - j + k - 1) / k;
      ans = min(ans, horizontal(j, y) + (x - j + k - 1) / k);
    }
  }
  return ans;
}

int horizontal(int x, int y) {
  // cout << "h " << x << ' ' << y << endl;
  if (x == x2 && y == y2) {
    return 0;
  }
  int ans = INF;
  for (int j = y + 1; j < w && grid[x][j] == '.'; j++) {
    if (dist[x][j] > dist[x][y] + (j - y + k - 1) / k) {
      dist[x][j] = dist[x][y] + (j - y + k - 1) / k;
      ans = min(ans, vertical(x, j) + (j - y + k - 1) / k);
    }
  }
  for (int j = y - 1; j >= 0 && grid[x][j] == '.'; j--) {
    if (dist[x][j] > dist[x][y] + (y - j + k - 1) / k) {
      dist[x][j] = dist[x][y] + (y - j + k - 1) / k;
      ans = min(ans, vertical(x, j) + (y - j + k - 1) / k);
    }
  }
  return ans;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cin >> h >> w >> k;
  int x1, y1;
  cin >> x1 >> y1 >> x2 >> y2;
  grid.resize(h);
  for (int i = 0; i < h; i++) {
    cin >> grid[i];
  }
  x1--;
  y1--;
  x2--;
  y2--;
  dist.assign(h, vector<int>(w, INF));
  dist[x1][y1] = 0;
  int ans = horizontal(x1, y1);
  dist.assign(h, vector<int>(w, INF));
  dist[x1][y1] = 0;
  ans = min(ans, vertical(x1, y1));
  if (ans == INF) {
    cout << -1 << '\\n';
    return 0;
  }
  cout << ans << '\\n';
  return 0;
}