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

#ifdef _MSC_VER
#include <__msvc_all_public_headers.hpp>
#undef min
#undef max
#else
#define NDEBUG
#include <bits/stdc++.h>
#endif

using namespace std;
using large = long long;

#define cell(g, i, j) (g)[((i) + 4) * (w + 8) + ((j) + 4)]

static int solve(const int h, const int w, const large k, const int x1,
                 const int y1, const int x2, const int y2) {
  auto grid = vector<char>((w + 8) * (h + 8), '@');
  auto mincost =
      vector<large>((w + 8) * (h + 8) * 4, numeric_limits<large>::max());
  for (auto i = 0; i < h; ++i)
    for (auto j = 0; j < w; ++j)
      cin >> cell(grid, i, j);

  if (cell(grid, x1, y1) == '@') {
    return -1;
  }
  if (cell(grid, x2, y2) == '@') {
    return -1;
  }

  const auto pack = [w](int x, int y, int d) {
    return 4 * ((x + 4) * (w + 8) + (y + 4)) + d;
  };
  const auto unpack = [w](int packed) {
    auto d = packed % 4;
    packed /= 4;
    auto y = packed % (w + 8);
    auto x = packed / (w + 8);
    return make_tuple(x - 4, y - 4, d);
  };

  auto Q = priority_queue<pair<large, int>>();
  const pair<int, int> mov[4] = {
      {0, 1},
      {0, -1},
      {1, 0},
      {-1, 0},
  };
  const auto direction_str = array<string, 4>{"R", "L", "D", "U"};
  const auto checked_push = [&](int x, int y, int d, large new_cost) {
    auto key = pack(x, y, d);
    if (mincost[key] <= new_cost) {
      return;
    }
    mincost[key] = new_cost;
    Q.push(make_pair(-new_cost, key));
  };

  for (auto d = 0; d < 4; ++d) {
    checked_push(x1, y1, d, 0);
  }

  while (!Q.empty()) {
    const auto c = -(Q.top().first);
    const auto key = Q.top().second;
    Q.pop();

    if (mincost[key] != c)
      continue;
    const auto [x, y, d] = unpack(key);

    if (x == x2 && y == y2)
      return (c + k - 1) / k;

    for (auto d_next = 0; d_next < 4; ++d_next) {
      if (d_next != d) {
        checked_push(x, y, d_next, (c + k - 1) / k * k);
      }
    }

    const auto [dirx, diry] = mov[d];
    const auto nx = x + dirx;
    const auto ny = y + diry;
    if (cell(grid, nx, ny) == '.') {
      checked_push(nx, ny, d, c + 1);
    }
  }

  return -1;
}

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

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

  x1--, y1--;
  x2--, y2--;
  cout << solve(h, w, k, x1, y1, x2, y2) << endl;
  return 0;
}


Error: TLE

Fixed submission:

#ifdef _MSC_VER
#include <__msvc_all_public_headers.hpp>
#undef min
#undef max
#else
#define NDEBUG
#include <bits/stdc++.h>
#endif

using namespace std;
using large = long long;

#define cell(g, i, j) (g)[((i) + 4) * (w + 8) + ((j) + 4)]

static int solve(const int h, const int w, const int k, const int x1,
                 const int y1, const int x2, const int y2) {
  auto grid = vector<char>((w + 8) * (h + 8), '@');
  auto mincost = vector<int>((w + 8) * (h + 8) * 4, INT_MAX);
  for (auto i = 0; i < h; ++i)
    for (auto j = 0; j < w; ++j)
      cin >> cell(grid, i, j);

  if (cell(grid, x1, y1) == '@') {
    return -1;
  }
  if (cell(grid, x2, y2) == '@') {
    return -1;
  }

  const auto pack = [w](int x, int y, int d) {
    return 4 * ((x + 4) * (w + 8) + (y + 4)) + d;
  };
  const auto unpack = [w](int packed) {
    auto d = packed % 4;
    packed /= 4;
    auto y = packed % (w + 8);
    auto x = packed / (w + 8);
    return make_tuple(x - 4, y - 4, d);
  };

  auto Q = priority_queue<pair<int, int>>();
  const pair<int, int> mov[4] = {
      {0, 1},
      {0, -1},
      {1, 0},
      {-1, 0},
  };
  const auto direction_str = array<string, 4>{"R", "L", "D", "U"};
  const auto checked_push = [&](int x, int y, int d, int new_cost) {
    auto key = pack(x, y, d);
    if (mincost[key] <= new_cost) {
      return;
    }
    mincost[key] = new_cost;
    Q.push(make_pair(-new_cost, key));
  };

  checked_push(x1, y1, 0, 0);

  while (!Q.empty()) {
    const auto c = -(Q.top().first);
    const auto [x, y, d] = unpack(Q.top().second);
    Q.pop();

    if (x == x2 && y == y2)
      return (c + k - 1) / k;

    for (auto d_next = 0; d_next < 4; ++d_next) {
      if (d_next != d) {
        checked_push(x, y, d_next, (c + k - 1) / k * k);
      }
    }

    const auto [dirx, diry] = mov[d];
    for (auto dist = 1; dist <= k; ++dist) {
      const auto nx = x + dirx * dist;
      const auto ny = y + diry * dist;
      if (cell(grid, nx, ny) == '@') {
        break;
      }

      checked_push(nx, ny, d, c + dist);
    }
  }

  return -1;
}

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

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

  x1--, y1--;
  x2--, y2--;
  cout << solve(h, w, k, x1, y1, x2, y2) << endl;
  return 0;
}