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

#include <bits/stdc++.h>

using namespace std;

#define REP(i, a, b) for (int i = a; i < (int)b; i++)
#define rep(i, n) REP(i, 0, n)
#define all(c) (c).begin(), (c).end()
#define zero(a) memset(a, 0, sizeof a)
#define minus(a) memset(a, -1, sizeof a)
#define watch(a)                                                               \\
  { cout << #a << " = " << a << endl; }
template <class T1, class T2> inline bool minimize(T1 &a, T2 b) {
  return b < a && (a = b, 1);
}
template <class T1, class T2> inline bool maximize(T1 &a, T2 b) {
  return a < b && (a = b, 1);
}

typedef long long ll;
int const inf = 1 << 29;

enum Face : int {
  Top = 0,
  Front = 1,
  Right = 2,
  Left = 3,
  Back = 4,
  Bottom = 5
};
class cube {
private:
  int f[6];
  unordered_map<int, string> name_;

public:
  cube() {}
  cube(vector<int> const &vs) {
    assert(vs.size() == 6);
    for (int i = 0; i < 6; i++)
      f[i] = vs[i];
  }
  cube(vector<string> const &vs) {
    assert(vs.size() == 6);
    for (int i = 0; i < 6; i++)
      f[i] = i, name_[i] = vs[i];
  }
  void roll_z() { roll(1, 2, 4, 3); }
  void roll_y() { roll(0, 2, 5, 3); }
  void roll_x() { roll(0, 1, 5, 4); }
  void roll(int i, int j, int k, int l) {
    int t = f[i];
    f[i] = f[j];
    f[j] = f[k];
    f[k] = f[l];
    f[l] = t;
  }

  const int &operator[](int idx) const { return f[idx]; }
  const string &name(int idx) { return name_[f[idx]]; }

  void roll(int k) {
    if (k == 0)
      roll_y();
    if (k == 1)
      roll_x();
    if (k == 2)
      for (int i = 0; i < 3; i++)
        roll_y();
    if (k == 3)
      for (int i = 0; i < 3; i++)
        roll_x();
  }

  bool roll_top_front(int top, int front) {
    for (int k = 0; k < 6; (k & 1 ? roll_y() : roll_x()), k++)
      for (int i = 0; i < 4; roll_z(), ++i)
        if (top == f[Top] && front == f[Front])
          return true;
    return false;
  }

  bool operator==(cube const &rhs) const {
    for (int i = 0; i < 6; i++)
      if (f[i] != rhs.f[i])
        return false;
    return true;
  }

  bool isomorphic(cube rhs) const {
    for (int k = 0; k < 6; (k & 1 ? rhs.roll_y() : rhs.roll_x()), k++)
      for (int i = 0; i < 4; rhs.roll_z(), ++i)
        if (operator==(rhs))
          return true;
    return false;
  }
};

int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, -1, 0, 1};
template <class T> constexpr bool in_range(T y, T x, T H, T W) {
  return 0 <= y && y < H && 0 <= x && x < W;
}

int main() {
  for (int W, H; cin >> W >> H && (W | H);) {
    vector<string> G(H);
    rep(i, H) cin >> G[i];
    string S;
    cin >> S;
    int sy, sx;
    rep(i, H) rep(j, W) if (G[i][j] == '#') sy = i, sx = j;
    G[sy][sx] = 'w';
    queue<tuple<cube, int, int, int>> q;
    cube c({"red", "magenta", "blue", "yellow", "green", "cyan"});
    q.emplace(c, sy, sx, 0);
    static int dist[33][33][7][7][8];
    rep(i, 33) rep(j, 33) rep(k, 7) rep(l, 7) rep(m, 8) dist[i][j][k][l][m] =
        inf;
    dist[sy][sx][c[Top]][c[Front]][0] = 0;
    while (!q.empty()) {
      cube c;
      int y, x, col;
      tie(c, y, x, col) = q.front();
      q.pop();
      if (col == 6) {
        cout << dist[y][x][c[Top]][c[Front]][col] << endl;
        goto next_f;
      }
      rep(k, 4) {
        int ny = y + dy[k], nx = x + dx[k];
        if (!in_range(ny, nx, H, W))
          continue;
        if (G[ny][nx] == 'k')
          continue;
        cube nc = c;
        nc.roll(k);
        if (G[ny][nx] != 'w' &&
            (G[ny][nx] != S[col] || nc.name(Top)[0] != S[col]))
          continue;
        int ncol = col + (G[ny][nx] == S[col] && nc.name(Top)[0] == S[col]);
        if (dist[ny][nx][nc[Top]][nc[Front]][ncol] < inf)
          continue;
        bool ng = 0;
        rep(t, 7) rep(f, 7) rep(k, ncol) ng |=
            G[ny][nx] != 'w' && (dist[ny][nx][t][f][k] < inf);
        if (ng)
          continue;
        dist[ny][nx][nc[Top]][nc[Front]][ncol] =
            dist[y][x][c[Top]][c[Front]][col] + 1;
        q.emplace(nc, ny, nx, ncol);
      }
    }
    cout << "unreachable" << endl;
  next_f:;
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

#define REP(i, a, b) for (int i = a; i < (int)b; i++)
#define rep(i, n) REP(i, 0, n)
#define all(c) (c).begin(), (c).end()
#define zero(a) memset(a, 0, sizeof a)
#define minus(a) memset(a, -1, sizeof a)
#define watch(a)                                                               \\
  { cout << #a << " = " << a << endl; }
template <class T1, class T2> inline bool minimize(T1 &a, T2 b) {
  return b < a && (a = b, 1);
}
template <class T1, class T2> inline bool maximize(T1 &a, T2 b) {
  return a < b && (a = b, 1);
}

typedef long long ll;
int const inf = 1 << 29;

enum Face : int {
  Top = 0,
  Front = 1,
  Right = 2,
  Left = 3,
  Back = 4,
  Bottom = 5
};
class cube {
private:
  int f[6];
  unordered_map<int, string> name_;

public:
  cube() {}
  cube(vector<int> const &vs) {
    assert(vs.size() == 6);
    for (int i = 0; i < 6; i++)
      f[i] = vs[i];
  }
  cube(vector<string> const &vs) {
    assert(vs.size() == 6);
    for (int i = 0; i < 6; i++)
      f[i] = i, name_[i] = vs[i];
  }
  void roll_z() { roll(1, 2, 4, 3); }
  void roll_y() { roll(0, 2, 5, 3); }
  void roll_x() { roll(0, 1, 5, 4); }
  void roll(int i, int j, int k, int l) {
    int t = f[i];
    f[i] = f[j];
    f[j] = f[k];
    f[k] = f[l];
    f[l] = t;
  }

  const int &operator[](int idx) const { return f[idx]; }
  const string &name(int idx) { return name_[f[idx]]; }

  void roll(int k) {
    if (k == 0)
      roll_y();
    if (k == 1)
      roll_x();
    if (k == 2)
      for (int i = 0; i < 3; i++)
        roll_y();
    if (k == 3)
      for (int i = 0; i < 3; i++)
        roll_x();
  }

  bool roll_top_front(int top, int front) {
    for (int k = 0; k < 6; (k & 1 ? roll_y() : roll_x()), k++)
      for (int i = 0; i < 4; roll_z(), ++i)
        if (top == f[Top] && front == f[Front])
          return true;
    return false;
  }

  bool operator==(cube const &rhs) const {
    for (int i = 0; i < 6; i++)
      if (f[i] != rhs.f[i])
        return false;
    return true;
  }

  bool isomorphic(cube rhs) const {
    for (int k = 0; k < 6; (k & 1 ? rhs.roll_y() : rhs.roll_x()), k++)
      for (int i = 0; i < 4; rhs.roll_z(), ++i)
        if (operator==(rhs))
          return true;
    return false;
  }
};

int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, -1, 0, 1};
template <class T> constexpr bool in_range(T y, T x, T H, T W) {
  return 0 <= y && y < H && 0 <= x && x < W;
}

int main() {
  for (int W, H; cin >> W >> H && (W | H);) {
    vector<string> G(H);
    rep(i, H) cin >> G[i];
    string S;
    cin >> S;
    int sy, sx;
    rep(i, H) rep(j, W) if (G[i][j] == '#') sy = i, sx = j;
    G[sy][sx] = 'w';
    queue<tuple<cube, int, int, int>> q;
    cube c({"red", "magenta", "blue", "yellow", "green", "cyan"});
    q.emplace(c, sy, sx, 0);
    static int dist[33][33][7][7][8];
    rep(i, 33) rep(j, 33) rep(k, 7) rep(l, 7) rep(m, 8) dist[i][j][k][l][m] =
        inf;
    dist[sy][sx][c[Top]][c[Front]][0] = 0;
    while (!q.empty()) {
      cube c;
      int y, x, col;
      tie(c, y, x, col) = q.front();
      q.pop();
      if (col == 6) {
        cout << dist[y][x][c[Top]][c[Front]][col] << endl;
        goto next_f;
      }
      rep(k, 4) {
        int ny = y + dy[k], nx = x + dx[k];
        if (!in_range(ny, nx, H, W))
          continue;
        if (G[ny][nx] == 'k')
          continue;
        cube nc = c;
        nc.roll(k);
        if (G[ny][nx] != 'w' &&
            (G[ny][nx] != S[col] || nc.name(Top)[0] != S[col]))
          continue;
        int ncol = col + (G[ny][nx] == S[col] && nc.name(Top)[0] == S[col]);
        if (dist[ny][nx][nc[Top]][nc[Front]][ncol] < inf)
          continue;
        bool ng = 0;
        rep(t, 7) rep(f, 7) rep(k, ncol) ng |=
            G[ny][nx] != 'w' && (dist[ny][nx][t][f][k] < inf);
        if (ng)
          continue;
        dist[ny][nx][nc[Top]][nc[Front]][ncol] =
            dist[sy][sx][c[Top]][c[Front]][0] + 1;
        q.emplace(nc, ny, nx, ncol);
      }
    }
    cout << "unreachable" << endl;
  next_f:;
  }
  return 0;
}