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

#include "bits/stdc++.h"
using namespace std;
int dx[2][3] = {{0, -1, 1}, {0, 1, -1}};
int dy[2][3] = {{1, 0, 0}, {-1, 0, 0}};
struct poly {
  int x;
  int y;
  int under;
  int front;
  int left;
  int right;
  int turn;
  int id;
  poly() : x(101), y(101), under(0), front(5), turn(0), id(0) { setlr(); }
  enum Way {
    W_Front,
    W_Left,
    W_Right,
  };
  int typeflr[4][3] = {{1, 0, 0}, {-1, 1, 1}, {1, -1, -1}, {-1, 0, 0}};
  int dflr[4][3] = {
      {0, 4, 1},
      {0, 1, 0},
      {0, 4, 0},
      {0, 1, 4},
  };
  // 0 5 4 1
  // 1 6 0 2
  // 5 0 11 10
  // 6 1 12 11
  // 10 15 9 5
  // 11 16 5 6
  // 15 10 16 19
  //  16 11 17 15
  void setid() {
    const int ftype = under / 5;
    const int fnum = under % 5;
    bool flag = false;
    for (int i = 0; i < 3; ++i) {
      const int atype = ftype + typeflr[ftype][i];
      const int anum = (fnum + dflr[ftype][i]) % 5;
      const int predict_front = atype * 5 + anum;
      if (predict_front == front) {
        id = i;
        break;
      }
    }
  }
  void setlr() {

    const int ftype = under / 5;
    const int fnum = under % 5;
    bool flag = false;
    for (int i = 0; i < 3; ++i) {
      const int atype = ftype + typeflr[ftype][i];
      const int anum = (fnum + dflr[ftype][i]) % 5;
      const int predict_front = atype * 5 + anum;
      if (predict_front == front) {
        {
          const int atype = ftype + typeflr[ftype][(i + 1) % 3];
          const int anum = (fnum + dflr[ftype][(i + 1) % 3]) % 5;
          left = atype * 5 + anum;
        }
        {
          const int atype = ftype + typeflr[ftype][(i + 2) % 3];
          const int anum = (fnum + dflr[ftype][(i + 2) % 3]) % 5;
          right = atype * 5 + anum;
        }
        flag = true;
        break;
      }
    }
    assert(flag);
  }
  void rotate_l() {
    int c = left;
    left = right;
    right = front;
    front = c;
  }
  void rotate(const Way way) {
    x += dx[(x + y) % 2][way];
    y += dy[(x + y) % 2][way];
    if (way == W_Front) {
      swap(front, under);
      setlr();
    } else if (way == W_Left) {
      swap(left, under);
      {
        rotate_l();
        setlr();
        rotate_l();
        rotate_l();
      }
    } else {
      swap(right, under);
      {
        rotate_l();
        rotate_l();
        setlr();
        rotate_l();
      }
    }
    setid();
    turn++;
  }
  void rotate(const int way) { rotate(static_cast<Way>(way)); }
};

int main() {
  while (1) {
    int x, y, u;
    cin >> x >> y >> u;
    if (!x && !y && !u)
      break;
    x += 101;
    y += 101;

    vector<vector<vector<vector<int>>>> memo(
        203, vector<vector<vector<int>>>(
                 203, vector<vector<int>>(20, vector<int>(3, 1e9))));
    queue<poly> que;
    memo[101][101][0][0] = 0;
    que.push(poly());
    int ans = -1;
    while (!que.empty()) {
      poly atop(que.front());
      if (atop.x == x && atop.y == y && atop.under == u) {
        ans = atop.turn;
        break;
      }
      que.pop();
      for (int i = 0; i < 3; ++i) {
        poly apoly(atop);
        apoly.rotate(i);
        if (memo[apoly.x][apoly.y][apoly.under][apoly.id] > apoly.turn) {
          memo[apoly.x][apoly.y][apoly.under][apoly.id] = apoly.turn;
          que.push(apoly);
        }
      }
    }
    cout << ans << endl;
  }
  return 0;
}

Error: MLE

Fixed submission:

#include "bits/stdc++.h"
using namespace std;
int dx[2][3] = {{0, -1, 1}, {0, 1, -1}};
int dy[2][3] = {{1, 0, 0}, {-1, 0, 0}};
struct poly {
  int x;
  int y;
  int under;
  int front;
  int left;
  int right;
  int turn;
  poly() : x(101), y(101), under(0), front(5), turn(0) { setlr(); }
  enum Way {
    W_Front,
    W_Left,
    W_Right,
  };
  // 0 5 4 1
  // 1 6 0 2
  // 5 0 11 10
  // 6 1 12 11
  // 10 15 9 5
  // 11 16 5 6
  // 15 10 16 19
  //  16 11 17 15
  void setlr() {
    int typeflr[4][3] = {{1, 0, 0}, {-1, 1, 1}, {1, -1, -1}, {-1, 0, 0}};
    int dflr[4][3] = {
        {0, 4, 1},
        {0, 1, 0},
        {0, 4, 0},
        {0, 1, 4},
    };
    const int ftype = under / 5;
    const int fnum = under % 5;
    bool flag = false;
    for (int i = 0; i < 3; ++i) {
      const int atype = ftype + typeflr[ftype][i];
      const int anum = (fnum + dflr[ftype][i]) % 5;
      const int predict_front = atype * 5 + anum;
      if (predict_front == front) {
        {
          const int atype = ftype + typeflr[ftype][(i + 1) % 3];
          const int anum = (fnum + dflr[ftype][(i + 1) % 3]) % 5;
          left = atype * 5 + anum;
        }
        {
          const int atype = ftype + typeflr[ftype][(i + 2) % 3];
          const int anum = (fnum + dflr[ftype][(i + 2) % 3]) % 5;
          right = atype * 5 + anum;
        }
        flag = true;
        break;
      }
    }
    assert(flag);
  }
  void rotate_l() {
    int c = left;
    left = right;
    right = front;
    front = c;
  }
  void rotate(const Way way) {
    x += dx[(x + y) % 2][way];
    y += dy[(x + y) % 2][way];
    if ((x + y) % 2) {
    }
    if (way == W_Front) {
      swap(front, under);
      setlr();
    } else if (way == W_Left) {
      swap(left, under);
      {
        rotate_l();
        setlr();
        rotate_l();
        rotate_l();
      }
    } else {
      swap(right, under);
      {
        rotate_l();
        rotate_l();
        setlr();
        rotate_l();
      }
    }
    turn++;
  }
  void rotate(const int way) { rotate(static_cast<Way>(way)); }
};

int main() {
  while (1) {
    int x, y, u;
    cin >> x >> y >> u;
    if (!x && !y && !u)
      break;
    x += 101;
    y += 101;

    vector<vector<vector<vector<int>>>> memo(
        203, vector<vector<vector<int>>>(
                 203, vector<vector<int>>(20, vector<int>(20, 1e9))));
    queue<poly> que;
    memo[101][101][0][5] = 0;
    que.push(poly());
    int ans = -1;
    while (!que.empty()) {
      poly atop(que.front());
      if (atop.x == x && atop.y == y && atop.under == u) {
        ans = atop.turn;
        break;
      }
      que.pop();
      for (int i = 0; i < 3; ++i) {
        poly apoly(atop);
        apoly.rotate(i);
        if (memo[apoly.x][apoly.y][apoly.under][apoly.front] > apoly.turn) {
          memo[apoly.x][apoly.y][apoly.under][apoly.front] = apoly.turn;
          que.push(apoly);
        }
      }
    }
    cout << ans << endl;
  }
  return 0;
}