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

#include <algorithm>
#include <cstring>
#include <iostream>
#include <queue>
#include <tuple>
#include <vector>

using namespace std;

#define REP(i, n) for (int i = 0; i < (int)n; i++)
#define REPS(i, n) for (int i = 1; i <= (int)n; i++)

typedef vector<int> vi;
typedef pair<int, int> pii;

int d[10] = {0, -1, 0, 1, 0, -1, 0, 1, 0, -1};
int w, h, s1, s2, t1, t2;

char ss[100][100];
int encode(int x, int y, int d) { return x * 16 * 4 + y * 4 + d; }

unsigned char dp[64 * 16 * 4][64 * 16 * 4];
unsigned char dp2[64 * 16 * 4];
int main() {
  while (cin >> w >> h, w) {
    REP(i, h) cin >> ss[i];
    vector<vi> g(64 * 16 * 4, vi(2, -1));
    vector<vector<vi>> invg(64 * 16 * 4, vector<vi>(2));
    REP(i, h) REP(j, w) if (ss[i][j] != '#') {
      REP(k, 4) if (ss[i + d[k]][j + d[k + 1]] == '.') {
        int dx = j, dy = i;
        while (ss[dy + d[k]][dx + d[k + 1]] != '#') {
          dy += d[k];
          dx += d[k + 1];
        }
        if (ss[i][j] == 'K') {
          s1 = encode(dx, dy, k);
          s2 = encode(j, i, k);
        }
        if (ss[i][j] == 'M') {
          t1 = encode(j, i, k ^ 2);
          t2 = encode(dx, dy, k);
        }
      }
      REP(k, 4) REP(l, 2) {
        int dx = j, dy = i;
        int dir = (k + 1 + l * 2) % 4;
        while (ss[dy + d[dir]][dx + d[dir + 1]] != '#') {
          dy += d[dir];
          dx += d[dir + 1];
        }
        int u = encode(j, i, k);
        int v = encode(dx, dy, dir);
        invg[v][!l].push_back(u);
        g[u][l] = v;
      }
    }
    memset(dp, 0, sizeof(dp));
    memset(dp2, 0, sizeof(dp2));
    queue<pii> q;
    REPS(i, 3) q.emplace(s1, s2 ^ i);
    int ans = 0;
    while (!q.empty()) {
      int u1, u2;
      tie(u1, u2) = q.front();
      q.pop();
      if ((u1 | 3) == (t1 | 3))
        ans = 1;
      if ((u1 | 3) == (t1 | 3) && u2 == t2) {
        ans = 2;
        break;
      }
      REP(l, 2) {
        int v1 = g[u1][l];
        if (u2 == -1 || invg[u2][l].empty()) {
          if (!dp2[v1]) {
            dp2[v1] = 1;
            q.emplace(v1, -1);
          }
        } else
          for (int v2 : invg[u2][l]) {
            if (!dp[v1][v2]) {
              dp[v1][v2] = 1;
              q.emplace(v1, v2);
            }
          }
      }
    }
    if (ans == 0)
      puts("He cannot bring tea to his master.");
    if (ans == 1)
      puts("He cannot return to the kitchen.");
    if (ans == 2)
      puts("He can accomplish his mission.");
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cstring>
#include <iostream>
#include <queue>
#include <tuple>
#include <vector>

using namespace std;

#define REP(i, n) for (int i = 0; i < (int)n; i++)
#define REPS(i, n) for (int i = 1; i <= (int)n; i++)

typedef vector<int> vi;
typedef pair<int, int> pii;

int d[10] = {0, -1, 0, 1, 0, -1, 0, 1, 0, -1};
int w, h, s1, s2, t1, t2;

char ss[100][100];
int encode(int x, int y, int d) { return x * 16 * 4 + y * 4 + d; }

int dp[64 * 16 * 4][64 * 16 * 4];
int dp2[64 * 16 * 4];
int main() {
  while (cin >> w >> h, w) {
    REP(i, h) cin >> ss[i];
    vector<vi> g(64 * 16 * 4, vi(2, -1));
    vector<vector<vi>> invg(64 * 16 * 4, vector<vi>(2));
    REP(i, h) REP(j, w) if (ss[i][j] != '#') {
      REP(k, 4) if (ss[i + d[k]][j + d[k + 1]] == '.') {
        int dx = j, dy = i;
        while (ss[dy + d[k]][dx + d[k + 1]] != '#') {
          dy += d[k];
          dx += d[k + 1];
        }
        if (ss[i][j] == 'K') {
          s1 = encode(dx, dy, k);
          s2 = encode(j, i, k);
        }
        if (ss[i][j] == 'M') {
          t1 = encode(j, i, k ^ 2);
          t2 = encode(dx, dy, k);
        }
      }
      REP(k, 4) REP(l, 2) {
        int dx = j, dy = i;
        int dir = (k + 1 + l * 2) % 4;
        while (ss[dy + d[dir]][dx + d[dir + 1]] != '#') {
          dy += d[dir];
          dx += d[dir + 1];
        }
        int u = encode(j, i, k);
        int v = encode(dx, dy, dir);
        invg[v][!l].push_back(u);
        g[u][l] = v;
      }
    }
    memset(dp, 0, sizeof(dp));
    memset(dp2, 0, sizeof(dp2));
    queue<pii> q;
    REPS(i, 3) q.emplace(s1, s2 ^ i);
    int ans = 0;
    while (!q.empty()) {
      int u1, u2;
      tie(u1, u2) = q.front();
      q.pop();
      if ((u1 | 3) == (t1 | 3))
        ans = 1;
      if ((u1 | 3) == (t1 | 3) && u2 == t2) {
        ans = 2;
        break;
      }
      REP(l, 2) {
        int v1 = g[u1][l];
        if (u2 == -1 || invg[u2][l].empty()) {
          if (!dp2[v1]) {
            dp2[v1] = 1;
            q.emplace(v1, -1);
          }
        } else
          for (int v2 : invg[u2][l]) {
            if (!dp[v1][v2]) {
              dp[v1][v2] = 1;
              q.emplace(v1, v2);
            }
          }
      }
    }
    if (ans == 0)
      puts("He cannot bring tea to his master.");
    if (ans == 1)
      puts("He cannot return to the kitchen.");
    if (ans == 2)
      puts("He can accomplish his mission.");
  }
  return 0;
}