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

#include <algorithm>
#include <array>
#include <cassert>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <unordered_set>
#include <vector>
#define repeat_from(i, m, n) for (int i = (m); (i) < (n); ++(i))
#define repeat(i, n) repeat_from(i, 0, n)
#define repeat_from_reverse(i, m, n) for (int i = (n)-1; (i) >= (m); --(i))
#define repeat_reverse(i, n) repeat_from_reverse(i, 0, n)
#define dump(x) cerr << #x << " = " << (x) << endl
#define debug(x)                                                               \\
  cerr << #x << " = " << (x) << " (L" << __LINE__ << ")"                       \\
       << " " << __FILE__ << endl
using namespace std;

// Wn R   Wr B
//   BWB    RWR
//    R      B
// Bn R   Br W
//   WBW    RBR
//    R      W
// Rn W   Rr B
//   BRB    WRW
//    W      B
const char Wn = 'W';
const char Wr = 'w';
const char Bn = 'B';
const char Br = 'b';
const char Rn = 'R';
const char Rr = 'r';
const char E = 'E';
char next_tate(char dice) {
  return dice == Wn   ? Rn
         : dice == Wr ? Br
         : dice == Bn ? Rr
         : dice == Br ? Wr
         : dice == Rn ? Wn
         : dice == Rr ? Bn
                      : 0;
}
char next_yoko(char dice) {
  return dice == Wn   ? Bn
         : dice == Wr ? Rr
         : dice == Bn ? Wn
         : dice == Br ? Rn
         : dice == Rn ? Br
         : dice == Rr ? Wr
                      : 0;
}
struct state_t {
  char f[3][3];
  int8_t ey, ex;
  int8_t n;
  int8_t match;
};
bool equals_top(char const (&f)[3][3], char const (&g)[3][3]) {
  repeat(y, 3) repeat(x, 3) {
    if (toupper(f[y][x]) != toupper(g[y][x])) {
      // if (toupper(f[y][x] != toupper(g[y][x]))) {
      return false;
    }
  }
  return true;
}
const int dy[] = {-1, 1, 0, 0};
const int dx[] = {0, 0, -1, 1};
uint32_t pack(char const (&f)[3][3]) {
  uint32_t z = 0;
  repeat(y, 3) {
    repeat(x, 3) {
      z *= 7;
      z += f[y][x] == Wn   ? 1
           : f[y][x] == Wr ? 2
           : f[y][x] == Bn ? 3
           : f[y][x] == Br ? 4
           : f[y][x] == Rn ? 5
           : f[y][x] == Rr ? 6
                           : 0;
    }
  }
  return z;
}

int main() {
  while (true) {
    int sex, sey;
    cin >> sex >> sey;
    if (sex == 0 and sey == 0)
      break;
    --sex;
    --sey;
    char goal[3][3];
    repeat(y, 3) repeat(x, 3) cin >> goal[y][x];
    unordered_set<uint32_t> used;
    queue<state_t> que;
    {
      state_t s;
      repeat(y, 3) repeat(x, 3) s.f[y][x] = Wn;
      s.f[sey][sex] = E;
      s.ey = sey;
      s.ex = sex;
      s.n = 0;
      s.match = 0;
      repeat(y, 3) repeat(x, 3) if (goal[y][x] == s.f[y][x]) s.match += 1;
      que.push(s);
      used.insert(pack(s.f));
    }
    int result = -1;
    while (not que.empty()) {
      state_t s = que.front();
      que.pop();
      // repeat (y,3) {
      // repeat (x,3) {
      // cerr << s.f[y][x];
      // }
      // cerr << endl;
      // }
      // cerr << endl;
      if (equals_top(s.f, goal)) {
        result = s.n;
        break;
      }
      if (s.n == 30)
        continue;
      if (9 - s.match > 30 - s.n + 1)
        continue;
      repeat(i, 4) {
        state_t t = s;
        t.ey = s.ey + dy[i];
        t.ex = s.ex + dx[i];
        if (t.ey < 0 or 3 <= t.ey or t.ex < 0 or 3 <= t.ex)
          continue;
        assert(s.f[s.ey][s.ex] == E);
        if (toupper(t.f[s.ey][s.ex]) == goal[s.ey][s.ex])
          t.match -= 1;
        if (toupper(t.f[t.ey][t.ex]) == goal[t.ey][t.ex])
          t.match -= 1;
        t.f[s.ey][s.ex] =
            dx[i] ? next_yoko(t.f[t.ey][t.ex]) : next_tate(t.f[t.ey][t.ex]);
        t.f[t.ey][t.ex] = E;
        if (toupper(t.f[s.ey][s.ex]) == goal[s.ey][s.ex])
          t.match += 1;
        if (toupper(t.f[t.ey][t.ex]) == goal[t.ey][t.ex])
          t.match += 1;
        t.n += 1;
        if (used.count(pack(t.f)))
          continue;
        que.push(t);
        used.insert(pack(t.f));
      }
    }
    cout << result << endl;
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <array>
#include <cassert>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <unordered_set>
#include <vector>
#define repeat_from(i, m, n) for (int i = (m); (i) < (n); ++(i))
#define repeat(i, n) repeat_from(i, 0, n)
#define repeat_from_reverse(i, m, n) for (int i = (n)-1; (i) >= (m); --(i))
#define repeat_reverse(i, n) repeat_from_reverse(i, 0, n)
#define dump(x) cerr << #x << " = " << (x) << endl
#define debug(x)                                                               \\
  cerr << #x << " = " << (x) << " (L" << __LINE__ << ")"                       \\
       << " " << __FILE__ << endl
using namespace std;

typedef array<array<char, 3>, 3> a33;
// Wn R   Wr B
//   BWB    RWR
//    R      B
// Bn R   Br W
//   WBW    RBR
//    R      W
// Rn W   Rr B
//   BRB    WRW
//    W      B
const char Wn = 'W';
const char Wr = 'w';
const char Bn = 'B';
const char Br = 'b';
const char Rn = 'R';
const char Rr = 'r';
const char E = 'E';
char next_tate(char dice) {
  return dice == Wn   ? Rn
         : dice == Wr ? Br
         : dice == Bn ? Rr
         : dice == Br ? Wr
         : dice == Rn ? Wn
         : dice == Rr ? Bn
                      : 0;
}
char next_yoko(char dice) {
  return dice == Wn   ? Bn
         : dice == Wr ? Rr
         : dice == Bn ? Wn
         : dice == Br ? Rn
         : dice == Rn ? Br
         : dice == Rr ? Wr
                      : 0;
}
struct state_t {
  a33 f;
  int ey, ex;
  int n;
};
bool equals_top(a33 const &f, a33 const &g) {
  repeat(y, 3) repeat(x, 3) {
    if (toupper(f[y][x]) != toupper(g[y][x])) {
      return false;
    }
  }
  return true;
}
const int dy[] = {-1, 1, 0, 0};
const int dx[] = {0, 0, -1, 1};
uint64_t pack(a33 const &f) {
  uint64_t z = 0;
  repeat(y, 3) {
    repeat(x, 3) {
      z *= 7;
      z += f[y][x] == Wn   ? 1
           : f[y][x] == Wr ? 2
           : f[y][x] == Bn ? 3
           : f[y][x] == Br ? 4
           : f[y][x] == Rn ? 5
           : f[y][x] == Rr ? 6
                           : 0;
    }
  }
  return z;
}

int main() {
  while (true) {
    int sex, sey;
    cin >> sex >> sey;
    if (sex == 0 and sey == 0)
      break;
    --sex;
    --sey;
    a33 goal;
    repeat(y, 3) repeat(x, 3) cin >> goal[y][x];
    queue<state_t> que;
    {
      state_t s;
      repeat(y, 3) repeat(x, 3) s.f[y][x] = Wn;
      s.f[sey][sex] = E;
      s.ey = sey;
      s.ex = sex;
      s.n = 0;
      que.push(s);
    }
    unordered_set<uint64_t> used;
    int result = -1;
    while (not que.empty()) {
      state_t s = que.front();
      que.pop();
      if (used.count(pack(s.f)))
        continue;
      used.insert(pack(s.f));
      // repeat (y,3) {
      // repeat (x,3) {
      // cerr << s.f[y][x];
      // }
      // cerr << endl;
      // }
      // cerr << endl;
      if (equals_top(s.f, goal)) {
        result = s.n;
        break;
      }
      if (s.n == 30)
        continue;
      repeat(i, 4) {
        state_t t = s;
        t.ey = s.ey + dy[i];
        t.ex = s.ex + dx[i];
        if (t.ey < 0 or 3 <= t.ey or t.ex < 0 or 3 <= t.ex)
          continue;
        assert(s.f[s.ey][s.ex] == E);
        t.f[s.ey][s.ex] =
            dx[i] ? next_yoko(t.f[t.ey][t.ex]) : next_tate(t.f[t.ey][t.ex]);
        t.f[t.ey][t.ex] = E;
        t.n += 1;
        if (used.count(pack(t.f)))
          continue;
        que.push(t);
      }
    }
    cout << result << endl;
  }
  return 0;
}