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

#include <array>
#include <iostream>
#include <limits>
#include <list>
#include <queue>
#include <utility>

using namespace std;

struct Node {
  int y;
  int x;
  int dir;
};

void adjacent(int &x, int &y, int dir) {
  switch (dir) {
  case 0:
    y++;
    break;
  case 1:
    x++;
    break;
  case 2:
    y--;
    break;
  case 3:
    x--;
    break;
  }
}

long long MAX = numeric_limits<long long>::max();

struct MyGreater {
  bool operator()(const pair<Node, long long> &n1,
                  const pair<Node, long long> &n2) {
    return n1.second > n2.second;
  }
};

int main() {
  int h, w, k;
  cin >> h >> w >> k;
  int x1, y1, x2, y2;
  cin >> y1 >> x1 >> y2 >> x2;
  vector<vector<char>> c(h, vector<char>(w));
  for (int i = 0; i < h; i++)
    for (int j = 0; j < w; j++)
      cin >> c[i][j];

  vector<vector<array<long long, 4>>> dist(
      h, vector<array<long long, 4>>(w, {MAX, MAX, MAX, MAX}));
  vector<vector<array<bool, 4>>> visited(
      h, vector<array<bool, 4>>(w, {false, false, false, false}));
  for (int k = 0; k < 4; k++)
    dist[y1 - 1][x1 - 1][k] = 0;

  MyGreater myGreater;
  priority_queue<pair<Node, long long>, vector<pair<Node, long long>>,
                 MyGreater>
      q(myGreater);
  for (int i = 0; i < h; i++)
    for (int j = 0; j < w; j++)
      for (int k = 0; k < 4; k++)
        q.push({{i, j, k}, dist[i][j][k]});

  while (!q.empty()) {
    const auto &top = q.top();
    Node minNode = top.first;
    long long minDist = top.second;
    if (minDist == MAX)
      break;
    if (visited[minNode.y][minNode.x][minNode.dir]) {
      q.pop();
      continue;
    }

    int newX = minNode.x;
    int newY = minNode.y;
    adjacent(newX, newY, minNode.dir);
    if (!(newX < 0 || newX >= w || newY < 0 || newY >= h) &&
        (c[newY][newX] != '@') && (!visited[newY][newX][minNode.dir])) {
      long long newDist = minDist + 1;
      if (newDist < dist[newY][newX][minNode.dir]) {
        dist[newY][newX][minNode.dir] = newDist;
        q.push({{newY, newX, minNode.dir}, newDist});
      }
    }

    long long newRotationDist = minDist;
    if (minDist % k != 0)
      newRotationDist = (minDist / k + 1) * k;
    for (int dir = 0; dir < 4; dir++) {
      if (dir == minNode.dir)
        continue;
      if (newRotationDist < dist[minNode.y][minNode.x][dir]) {
        dist[minNode.y][minNode.x][dir] = newRotationDist;
        q.push({{minNode.y, minNode.x, dir}, newRotationDist});
      }
    }

    visited[minNode.y][minNode.x][minNode.dir] = true;
    q.pop();
  }

  long long minDist = MAX;
  for (int dir = 0; dir < 4; dir++) {
    long long temp = dist[y2 - 1][x2 - 1][dir];
    if (temp < minDist)
      minDist = temp;
  }
  if (minDist == MAX)
    cout << -1 << endl;
  else if (minDist % k == 0)
    cout << minDist / k << endl;
  else
    cout << minDist / k + 1 << endl;

  return 0;
}

Error: TLE

Fixed submission:

#include <array>
#include <iostream>
#include <list>
#include <queue>

using namespace std;

struct Node {
  int y;
  int x;
  int dir;
};

void adjacent(int &x, int &y, int dir) {
  switch (dir) {
  case 0:
    y++;
    break;
  case 1:
    x++;
    break;
  case 2:
    y--;
    break;
  case 3:
    x--;
    break;
  }
}

int main() {
  int h, w, k;
  cin >> h >> w >> k;
  int x1, y1, x2, y2;
  cin >> y1 >> x1 >> y2 >> x2;
  vector<vector<char>> c(h, vector<char>(w));
  for (int i = 0; i < h; i++)
    for (int j = 0; j < w; j++)
      cin >> c[i][j];

  list<Node> q;
  vector<vector<array<long long, 4>>> dist(
      h, vector<array<long long, 4>>(w, {-1, -1, -1, -1}));
  vector<vector<array<bool, 4>>> visited(
      h, vector<array<bool, 4>>(w, {false, false, false, false}));
  for (int i = 0; i < h; i++)
    for (int j = 0; j < w; j++)
      for (int k = 0; k < 4; k++)
        q.push_back({i, j, k});

  for (int k = 0; k < 4; k++)
    dist[y1 - 1][x1 - 1][k] = 0;

  while (!q.empty()) {
    long long minDist = -1;
    list<Node>::iterator minNode = q.end();
    for (list<Node>::iterator it = q.begin(); it != q.end(); it++) {
      long long temp = dist[it->y][it->x][it->dir];
      if (temp == -1)
        continue;
      if (minDist == -1 || temp < minDist) {
        minDist = temp;
        minNode = it;
      }
    }
    if (minNode == q.end())
      break;

    int newX = minNode->x;
    int newY = minNode->y;
    adjacent(newX, newY, minNode->dir);
    if (!(newX < 0 || newX >= w || newY < 0 || newY >= h) &&
        (c[newY][newX] != '@') && (!visited[newY][newX][minNode->dir])) {
      long long newDist = minDist + 1;
      if (dist[newY][newX][minNode->dir] == -1 ||
          newDist < dist[newY][newX][minNode->dir])
        dist[newY][newX][minNode->dir] = newDist;
    }

    long long newRotationDist = minDist;
    if (minDist % k != 0)
      newRotationDist = (minDist / k + 1) * k;
    for (int dir = 0; dir < 4; dir++) {
      if (dir == minNode->dir)
        continue;
      if (dist[minNode->y][minNode->x][dir] == -1 ||
          newRotationDist < dist[minNode->y][minNode->x][dir])
        dist[minNode->y][minNode->x][dir] = newRotationDist;
    }

    visited[minNode->y][minNode->x][minNode->dir] = true;
    q.erase(minNode);
  }

  long long minDist = -1;
  for (int dir = 0; dir < 4; dir++) {
    long long temp = dist[y2 - 1][x2 - 1][dir];
    if (temp == -1)
      continue;
    if (minDist == -1 || temp < minDist)
      minDist = temp;
  }
  if (minDist == -1)
    cout << -1 << endl;
  else if (minDist % k == 0)
    cout << minDist / k << endl;
  else
    cout << minDist / k + 1 << endl;

  return 0;
}