Problem p01459 (C++) — buggy submission, verdict: Memory Limit Exceeded

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<ll, ll> P;

#define each(i, a) for (auto &&i : a)
#define FOR(i, a, b) for (ll i = (a), __last_##i = (b); i < __last_##i; i++)
#define RFOR(i, a, b) for (ll i = (b)-1, __last_##i = (a); i >= __last_##i; i--)
#define REP(i, n) FOR(i, 0, n)
#define RREP(i, n) RFOR(i, 0, n)
#define __GET_MACRO3(_1, _2, _3, NAME, ...) NAME
#define rep(...) __GET_MACRO3(__VA_ARGS__, FOR, REP)(__VA_ARGS__)
#define rrep(...) __GET_MACRO3(__VA_ARGS__, RFOR, RREP)(__VA_ARGS__)
#define pb push_back
#define all(a) (a).begin(), (a).end()
#define chmin(x, v) x = min(x, v)
#define chmax(x, v) x = max(x, v)

const ll linf = 1e18;
const int inf = 1e9;
const double eps = 1e-12;
const double pi = acos(-1);

template <typename T> istream &operator>>(istream &is, vector<T> &vec) {
  each(x, vec) is >> x;
  return is;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
  rep(i, vec.size()) {
    if (i)
      os << " ";
    os << vec[i];
  }
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const vector<vector<T>> &vec) {
  rep(i, vec.size()) {
    if (i)
      os << endl;
    os << vec[i];
  }
  return os;
}

const ll dx[4] = {0, 1, 0, -1};
const ll dy[4] = {-1, 0, 1, 0};

P cost(ll d1, ll d2) {
  if (d1 == d2)
    return {0, 0};
  if ((d1 + 2) % 4 == d2)
    return {linf, linf};
  if ((d2 % 2) ^ ((d1 + 1) % 4 == d2))
    return {1, 0};
  return {0, 1};
}

struct Node {
  ll x, y, dir, p, q;
  ll cost;
};
bool operator>(const Node &n1, const Node &n2) { return n1.cost > n2.cost; }

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  ll h, w, A;
  cin >> h >> w >> A;
  vector<string> m(h);
  cin >> m;
  ll sx = -1, sy = -1;
  ll gx = -1, gy = -1;
  rep(y, h) rep(x, w) {
    if (m[y][x] == 'S') {
      sx = x, sy = y;
    }
    if (m[y][x] == 'G') {
      gx = x, gy = y;
    }
  }
  vector<vector<vector<vector<vector<ll>>>>> dist(
      h, vector<vector<vector<vector<ll>>>>(
             w, vector<vector<vector<ll>>>(
                    4, vector<vector<ll>>(A + 1, vector<ll>(A + 1, linf)))));
  dist[sy][sx][2][0][0] = 0;
  priority_queue<Node, vector<Node>, greater<Node>> Q;
  Q.push({sx, sy, 2, 0, 0, 0});
  auto inRange = [&](ll x, ll y) { return 0 <= x && x < w && 0 <= y && y < h; };
  while (!Q.empty()) {
    Node node = Q.top();
    Q.pop();
    ll x = node.x, y = node.y;
    ll dir = node.dir, p = node.p, q = node.q;
    // cout << x << " " << y << " " << dir << " " << p << " " << q << endl;
    if (node.cost > dist[y][x][dir][p][q])
      continue;
    rep(d, 4) {
      P c = cost(dir, d);
      ll np = p + c.first, nq = q + c.second;
      if (np > A || nq > A)
        continue;
      ll dc = c.first + c.second;
      ll nx = d == dir ? x + dx[d] : x;
      ll ny = d == dir ? y + dy[d] : y;
      // cout << "!" << nx << " " << ny << " " << d << endl;
      if ((d == 0 || d != dir) && x == sx && y == sy)
        continue;
      if (!inRange(nx, ny))
        continue;
      if (m[ny][nx] == '#')
        continue;
      if (dist[y][x][dir][p][q] + dc < dist[ny][nx][d][np][nq]) {
        dist[ny][nx][d][np][nq] = dist[y][x][dir][p][q] + dc;
        Q.push({nx, ny, d, np, nq, dist[ny][nx][d][np][nq]});
      }
    }
  }
  ll ans = linf;
  rep(d, 4) rep(p, A + 1) rep(q, A + 1) {
    // if (dist[gy][gx][d][p][q] >= 0) {
    chmin(ans, dist[gy][gx][d][p][q]);
    // }
  }
  if (ans == linf)
    ans = -1;
  cout << ans << endl;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <vector>

using namespace std;

int n, m;
char g[111][111];

int dp[101][101][101][11][4];

struct node {
  int x, y, first, use, dir;
  node() {}
  node(int a, int b, int c, int d, int e) {
    x = a;
    y = b;
    first = c;
    use = d;
    dir = e;
  }
};

int dx[] = {1, 0, -1, 0};
int dy[] = {0, 1, 0, -1};

bool isin(int x, int y) {
  return x >= 1 && x <= n && y >= 1 && y <= m && g[x][y] != '#';
}

int mp[4][4];
queue<node> Q;

int wherex[111], wherey[111];
int to[111][111];

int main() {
  memset(mp, -1, sizeof(mp));
  mp[0][1] = 0;
  mp[0][3] = 1;
  mp[1][0] = 0;
  mp[1][2] = 1;
  mp[2][3] = 0;
  mp[2][1] = 1;
  mp[3][2] = 0;
  mp[3][0] = 1;
  int a;
  while (~scanf("%d %d %d", &n, &m, &a)) {
    for (int i = 1; i <= n; i++)
      scanf("%s", g[i] + 1);
    memset(to, 0, sizeof(to));
    int cnt = 0;
    memset(dp, -1, sizeof(dp));
    for (int i = 1; i <= n; i++)
      for (int j = 1; j <= m; j++)
        if (g[i][j] == 'S') {
          if (i + 1 <= n) {
            dp[i + 1][j][0][0][0] = 0;
            Q.push(node(i + 1, j, 0, 0, 0));
            for (int k = i + 1; k <= n; k++) {
              ++cnt;
              wherex[cnt] = k;
              wherey[cnt] = j;
              to[k][j] = cnt;
            }
          }
        }
    int ans = -1;
    while (!Q.empty()) {
      node now = Q.front();
      Q.pop();
      int val = dp[now.x][now.y][now.first][now.use][now.dir];
      if (g[now.x][now.y] == 'G') {
        if (ans == -1 || ans > val + now.use) {
          ans = val + now.use;
        }
      }
      for (int i = 0; i < 4; i++)
        if (mp[now.dir][i] != -1) {
          int nxx = now.x + dx[i];
          int nxy = now.y + dy[i];
          if (now.first && wherex[now.first] == nxx && wherey[now.first] == nxy)
            continue;
          int use = mp[now.dir][i];
          if (isin(nxx, nxy)) {
            if (now.use + use <= a) {
              int nxval = val + (!use);
              if (nxval > a)
                continue;
              int nxfirst = now.first;
              if (nxfirst == 0)
                nxfirst = to[nxx][nxy];
              int &nx = dp[nxx][nxy][nxfirst][now.use + use][i];
              if (nx == -1 || nx > nxval) {
                nx = nxval;
                Q.push(node(nxx, nxy, nxfirst, now.use + use, i));
              }
            }
          }
        }

      int nxx = now.x + dx[now.dir];
      int nxy = now.y + dy[now.dir];
      if (isin(nxx, nxy)) {
        int &nx = dp[nxx][nxy][now.first][now.use][now.dir];
        if (nx == -1 || nx > val) {
          nx = val;
          Q.push(node(nxx, nxy, now.first, now.use, now.dir));
        }
      }
    }
    printf("%d\\n", ans);
  }
}