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

#include <bits/stdc++.h>
using namespace std;

void rA(int t[20]) {
  int u[20] = {5, 10, 15, 16, 11, 0, 9, 19, 17, 6,
               1, 4,  14, 18, 12, 2, 3, 8,  13, 7};
  int tmp[20];
  for (int i = 0; i < 20; i++)
    tmp[i] = t[u[i]];
  for (int i = 0; i < 20; i++)
    t[i] = tmp[i];
}

void rB(int t[20]) {
  int u[20] = {1, 0, 5, 11, 6,  2,  4, 10, 16, 12,
               7, 3, 9, 15, 17, 13, 8, 14, 19, 18};
  int tmp[20];
  for (int i = 0; i < 20; i++)
    tmp[i] = t[u[i]];
  for (int i = 0; i < 20; i++)
    t[i] = tmp[i];
}

void rC(int t[20]) {
  int u[20] = {4, 9, 10, 5,  0, 3, 14, 15, 11, 1,
               2, 8, 19, 16, 6, 7, 13, 18, 17, 12};
  int tmp[20];
  for (int i = 0; i < 20; i++)
    tmp[i] = t[u[i]];
  for (int i = 0; i < 20; i++)
    t[i] = tmp[i];
}

void rD(int t[20]) {
  int u[20] = {5, 10, 15, 16, 11, 0, 9, 19, 17, 6,
               1, 4,  14, 18, 12, 2, 3, 8,  13, 7};
  int tmp[20];
  for (int i = 0; i < 20; i++)
    tmp[i] = t[u[i]];
  for (int i = 0; i < 20; i++)
    t[i] = tmp[i];
}

void rE(int t[20]) {
  int u[20] = {1, 0, 5, 11, 6,  2,  4, 10, 16, 12,
               7, 3, 9, 15, 17, 13, 8, 14, 19, 18};
  int tmp[20];
  for (int i = 0; i < 20; i++)
    tmp[i] = t[u[i]];
  for (int i = 0; i < 20; i++)
    t[i] = tmp[i];
}

void rF(int t[20]) {
  int u[20] = {4, 9, 10, 5,  0, 3, 14, 15, 11, 1,
               2, 8, 19, 16, 6, 7, 13, 18, 17, 12};
  int tmp[20];
  for (int i = 0; i < 20; i++)
    tmp[i] = t[u[i]];
  for (int i = 0; i < 20; i++)
    t[i] = tmp[i];
}

struct die {
  int p[20];
  bool operator<(const die &A) const {
    for (int i = 0; i < 20; i++)
      if (p[i] != A.p[i])
        return (p[i] < A.p[i]);
    return false;
  }
};

typedef pair<int, int> P;
typedef pair<P, int> state;

typedef pair<P, int> PP;
typedef unsigned int ull;

map<ull, int> d;
map<PP, int> ans;
queue<state> Q;
map<die, int> dice;
map<int, die> redice;

int dieId(die d) {
  if (dice.count(d) > 0)
    return dice[d];
  int res = dice.size();
  dice[d] = res;
  redice[res] = d;
  return res;
}

int RA(int id) {
  static map<int, int> mp;
  if (mp.count(id) > 0)
    return mp[id];
  die d = redice[id];
  rA(d.p);
  mp[id] = dieId(d);
  return mp[id];
}
int RB(int id) {
  static map<int, int> mp;
  if (mp.count(id) > 0)
    return mp[id];
  die d = redice[id];
  rB(d.p);
  mp[id] = dieId(d);
  return mp[id];
}
int RC(int id) {
  static map<int, int> mp;
  if (mp.count(id) > 0)
    return mp[id];
  die d = redice[id];
  rC(d.p);
  mp[id] = dieId(d);
  return mp[id];
}
int RD(int id) {
  static map<int, int> mp;
  if (mp.count(id) > 0)
    return mp[id];
  die d = redice[id];
  rD(d.p);
  mp[id] = dieId(d);
  return mp[id];
}
int RE(int id) {
  static map<int, int> mp;
  if (mp.count(id) > 0)
    return mp[id];
  die d = redice[id];
  rE(d.p);
  mp[id] = dieId(d);
  return mp[id];
}
int RF(int id) {
  static map<int, int> mp;
  if (mp.count(id) > 0)
    return mp[id];
  die d = redice[id];
  rF(d.p);
  mp[id] = dieId(d);
  return mp[id];
}

ull getHash(state s) {
  ull res = 0, B = 5575777;
  int x = s.first.first + 150;
  int y = s.first.second + 150;
  res = x * B + y;
  die d = redice[s.second];
  for (int i = 0; i < 20; i++)
    res = res * B + d.p[i];
  return res;
}

void Push(state s, int cost) {
  ull key = getHash(s);
  if (d.count(key) > 0)
    return;
  d[key] = cost + 1;
  Q.push(s);
}

int main() {
  die v;
  for (int i = 0; i < 20; i++)
    v.p[i] = i;
  state si = state(P(0, 0), dieId(v));
  d[getHash(si)] = 0;
  Q.push(si);

  while (!Q.empty()) {
    state s = Q.front();
    Q.pop();
    int cost = d[getHash(s)];

    int x = s.first.first;
    int y = s.first.second;
    int f = abs(x + y) % 2;
    die d = redice[s.second];
    die tmpd = d;
    int n = d.p[0];

    /*
      cout<<x<<' '<<y<<' '<<cost<<' '<<n<<endl;
      for(int i=0;i<20;i++)cout<<s.second.p[i]<<' ';
      cout<<endl;
      cout<<endl;
    */
    if (ans.count(PP(P(x, y), n)) == 0)
      ans[PP(P(x, y), n)] = cost;

    if (cost == 100)
      continue;

    if (f == 0) {
      state A = s;
      A.first = P(x, y + 1);
      A.second = RA(s.second);
      Push(A, cost);

      state B = s;
      B.first = P(x + 1, y);
      B.second = RB(s.second);
      Push(B, cost);

      state C = s;
      C.first = P(x - 1, y);
      C.second = RC(s.second);
      Push(C, cost);

    } else {
      state D = s;
      D.first = P(x, y - 1);
      rD(d.p);
      D.second = RD(s.second);
      Push(D, cost);

      state E = s;
      E.first = P(x - 1, y);
      rE(d.p);
      E.second = RE(s.second);
      Push(E, cost);

      state F = s;
      F.first = P(x + 1, y);
      rF(d.p);
      F.second = RF(s.second);
      Push(F, cost);
    }
  }

  // cout<<dice.size()<<endl;

  while (1) {
    int x, y, n;
    cin >> x >> y >> n;
    if (x == 0 && y == 0 && n == 0)
      break;
    cout << ans[PP(P(x, y), n)] << endl;
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

void rA(int t[20]) {
  int u[20] = {5, 10, 15, 16, 11, 0, 9, 19, 17, 6,
               1, 4,  14, 18, 12, 2, 3, 8,  13, 7};
  int tmp[20];
  for (int i = 0; i < 20; i++)
    tmp[i] = t[u[i]];
  for (int i = 0; i < 20; i++)
    t[i] = tmp[i];
}

void rB(int t[20]) {
  int u[20] = {1, 0, 5, 11, 6,  2,  4, 10, 16, 12,
               7, 3, 9, 15, 17, 13, 8, 14, 19, 18};
  int tmp[20];
  for (int i = 0; i < 20; i++)
    tmp[i] = t[u[i]];
  for (int i = 0; i < 20; i++)
    t[i] = tmp[i];
}

void rC(int t[20]) {
  int u[20] = {4, 9, 10, 5,  0, 3, 14, 15, 11, 1,
               2, 8, 19, 16, 6, 7, 13, 18, 17, 12};
  int tmp[20];
  for (int i = 0; i < 20; i++)
    tmp[i] = t[u[i]];
  for (int i = 0; i < 20; i++)
    t[i] = tmp[i];
}

void rD(int t[20]) {
  int u[20] = {5, 10, 15, 16, 11, 0, 9, 19, 17, 6,
               1, 4,  14, 18, 12, 2, 3, 8,  13, 7};
  int tmp[20];
  for (int i = 0; i < 20; i++)
    tmp[i] = t[u[i]];
  for (int i = 0; i < 20; i++)
    t[i] = tmp[i];
}

void rE(int t[20]) {
  int u[20] = {1, 0, 5, 11, 6,  2,  4, 10, 16, 12,
               7, 3, 9, 15, 17, 13, 8, 14, 19, 18};
  int tmp[20];
  for (int i = 0; i < 20; i++)
    tmp[i] = t[u[i]];
  for (int i = 0; i < 20; i++)
    t[i] = tmp[i];
}

void rF(int t[20]) {
  int u[20] = {4, 9, 10, 5,  0, 3, 14, 15, 11, 1,
               2, 8, 19, 16, 6, 7, 13, 18, 17, 12};
  int tmp[20];
  for (int i = 0; i < 20; i++)
    tmp[i] = t[u[i]];
  for (int i = 0; i < 20; i++)
    t[i] = tmp[i];
}

struct die {
  int p[20];
  bool operator<(const die &A) const {
    for (int i = 0; i < 20; i++)
      if (p[i] != A.p[i])
        return (p[i] < A.p[i]);
    return false;
  }
};

typedef pair<int, int> P;
typedef pair<P, int> state;

typedef pair<P, int> PP;
typedef unsigned long long ull;

map<ull, int> d;
map<PP, int> ans;
queue<state> Q;
map<die, int> dice;
map<int, die> redice;

int dieId(die d) {
  if (dice.count(d) > 0)
    return dice[d];
  int res = dice.size();
  dice[d] = res;
  redice[res] = d;
  return res;
}

int RA(int id) {
  static map<int, int> mp;
  if (mp.count(id) > 0)
    return mp[id];
  die d = redice[id];
  rA(d.p);
  mp[id] = dieId(d);
  return mp[id];
}
int RB(int id) {
  static map<int, int> mp;
  if (mp.count(id) > 0)
    return mp[id];
  die d = redice[id];
  rB(d.p);
  mp[id] = dieId(d);
  return mp[id];
}
int RC(int id) {
  static map<int, int> mp;
  if (mp.count(id) > 0)
    return mp[id];
  die d = redice[id];
  rC(d.p);
  mp[id] = dieId(d);
  return mp[id];
}
int RD(int id) {
  static map<int, int> mp;
  if (mp.count(id) > 0)
    return mp[id];
  die d = redice[id];
  rD(d.p);
  mp[id] = dieId(d);
  return mp[id];
}
int RE(int id) {
  static map<int, int> mp;
  if (mp.count(id) > 0)
    return mp[id];
  die d = redice[id];
  rE(d.p);
  mp[id] = dieId(d);
  return mp[id];
}
int RF(int id) {
  static map<int, int> mp;
  if (mp.count(id) > 0)
    return mp[id];
  die d = redice[id];
  rF(d.p);
  mp[id] = dieId(d);
  return mp[id];
}

ull getHash(state s) {
  ull res = 0, B = 5575777;
  int x = s.first.first + 150;
  int y = s.first.second + 150;
  res = x * B + y;
  die d = redice[s.second];
  for (int i = 0; i < 20; i++)
    res = res * B + d.p[i];
  return res;
}

void Push(state s, int cost) {
  ull key = getHash(s);
  if (d.count(key) > 0)
    return;
  d[key] = cost + 1;
  Q.push(s);
}

int main() {
  die v;
  for (int i = 0; i < 20; i++)
    v.p[i] = i;
  state si = state(P(0, 0), dieId(v));
  d[getHash(si)] = 0;
  Q.push(si);

  while (!Q.empty()) {
    state s = Q.front();
    Q.pop();
    int cost = d[getHash(s)];

    int x = s.first.first;
    int y = s.first.second;
    int f = abs(x + y) % 2;
    die d = redice[s.second];
    die tmpd = d;
    int n = d.p[0];

    /*
      cout<<x<<' '<<y<<' '<<cost<<' '<<n<<endl;
      for(int i=0;i<20;i++)cout<<s.second.p[i]<<' ';
      cout<<endl;
      cout<<endl;
    */
    if (ans.count(PP(P(x, y), n)) == 0)
      ans[PP(P(x, y), n)] = cost;

    if (cost == 100)
      continue;

    if (f == 0) {
      state A = s;
      A.first = P(x, y + 1);
      A.second = RA(s.second);
      Push(A, cost);

      state B = s;
      B.first = P(x + 1, y);
      B.second = RB(s.second);
      Push(B, cost);

      state C = s;
      C.first = P(x - 1, y);
      C.second = RC(s.second);
      Push(C, cost);

    } else {
      state D = s;
      D.first = P(x, y - 1);
      rD(d.p);
      D.second = RD(s.second);
      Push(D, cost);

      state E = s;
      E.first = P(x - 1, y);
      rE(d.p);
      E.second = RE(s.second);
      Push(E, cost);

      state F = s;
      F.first = P(x + 1, y);
      rF(d.p);
      F.second = RF(s.second);
      Push(F, cost);
    }
  }

  // cout<<dice.size()<<endl;

  while (1) {
    int x, y, n;
    cin >> x >> y >> n;
    if (x == 0 && y == 0 && n == 0)
      break;
    cout << ans[PP(P(x, y), n)] << endl;
  }
  return 0;
}