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

#include <iostream>
#include <map>
#include <queue>
using namespace std;

unsigned long long int makeID(int (&p)[13]) {
  unsigned long long int ret = 0;
  for (int i = 0; i < 13; ++i) {
    ret *= 13;
    ret += p[i];
  }
  return ret;
}

unsigned long long int slide(unsigned long long int s, int a, int b) {
  int p[13];
  for (int i = 0; i < 13; ++i) {
    p[12 - i] = s % 13;
    s /= 13;
  }
  int t = p[a];
  p[a] = p[b];
  p[b] = t;
  return makeID(p);
}

int side[][4] = {{-1, -1, 2, -1},
                 {-1, 2, 5, -1},
                 {0, 3, 6, 1},
                 {-1, -1, 7, 2},
                 {-1, 5, -1, -1},
                 {1, 6, 9, 4},
                 {2, 7, 10, 5},
                 {3, 8, 11, 6},
                 {-1, -1, -1, 7},
                 {
                     5,
                     10,
                     -1,
                     -1,
                 },
                 {6, 11, 12, 9},
                 {7, -1, -1, 10},
                 {10, -1, -1, -1}};

int solve(map<unsigned long long int, int> &ans,
          queue<unsigned long long int> &q, int *p,
          map<unsigned long long int, int> *sub) {
  int cnt = 1;
  while (cnt <= 10) {
    int size = q.size();
    for (int i = 0; i < size; ++i) {
      unsigned long long int s = q.front();
      q.pop();
      int pos[2], a = 0;
      unsigned long long int t = s;
      for (int j = 0; j < 13; ++j) {
        int b = t % 13;
        if (b == 0)
          pos[a++] = 12 - j;
        t /= 13;
      }
      for (int j = 0; j < 2; ++j) {
        int b = pos[j];
        for (int k = 0; k < 4; ++k) {
          int c = side[b][k];
          if (c == -1)
            continue;
          t = slide(s, b, c);
          bool e = ans.find(t) == ans.end();
          if (sub == NULL) {
            if (e) {
              ans[t] = cnt;
              q.push(t);
            }
          } else {
            if (!e) {
              return ans[t] + cnt;
            } else if (sub->find(t) == sub->end()) {
              (*sub)[t] = cnt;
              q.push(t);
            }
          }
        }
      }
    }
    ++cnt;
  }
  return -1;
}

int main() {
  map<unsigned long long int, int> ans;
  queue<unsigned long long int> q;

  int p[13];
  for (int i = 0; i < 13; ++i) {
    p[i] = i;
  }
  p[12] = 0;
  unsigned long long int s = makeID(p);
  ans[s] = 0;
  q.push(s);

  solve(ans, q, p, NULL);

  while (!q.empty())
    q.pop();

  while (cin >> p[0] && p[0] != -1) {
    for (int i = 1; i < 13; ++i) {
      cin >> p[i];
    }
    queue<unsigned long long int> qq;
    s = makeID(p);
    qq.push(s);
    int r;
    map<unsigned long long int, int> u;
    if (ans.find(s) != ans.end()) {
      r = ans[s];
    } else {
      r = solve(ans, qq, p, &u);
    }
    if (r >= 0) {
      cout << r << endl;
    } else {
      cout << "NA" << endl;
    }
  }

  return 0;
}

Error: MLE

Fixed submission:

#include <iostream>
#include <map>
#include <queue>
using namespace std;

unsigned long long int makeID(int (&p)[13]) {
  unsigned long long int ret = 0;
  for (int i = 0; i < 13; ++i) {
    ret *= 13;
    ret += p[i];
  }
  return ret;
}

unsigned long long int slide(unsigned long long int s, int a, int b) {
  int p[13];
  for (int i = 0; i < 13; ++i) {
    p[12 - i] = s % 13;
    s /= 13;
  }
  int t = p[a];
  p[a] = p[b];
  p[b] = t;
  return makeID(p);
}

int main() {
  map<unsigned long long int, int> ans;
  queue<unsigned long long int> q;

  int side[][4] = {{-1, -1, 2, -1},
                   {-1, 2, 5, -1},
                   {0, 3, 6, 1},
                   {-1, -1, 7, 2},
                   {-1, 5, -1, -1},
                   {1, 6, 9, 4},
                   {2, 7, 10, 5},
                   {3, 8, 11, 6},
                   {-1, -1, -1, 7},
                   {
                       5,
                       10,
                       -1,
                       -1,
                   },
                   {6, 11, 12, 9},
                   {7, -1, -1, 10},
                   {10, -1, -1, -1}};

  int p[13];
  for (int i = 0; i < 13; ++i) {
    p[i] = i;
  }
  p[12] = 0;
  unsigned long long int s = makeID(p);
  ans[s] = 0;
  q.push(s);

  int cnt = 1;
  while (cnt < 20) {
    int size = q.size();
    for (int i = 0; i < size; ++i) {
      s = q.front();
      q.pop();
      int pos[2], a = 0;
      unsigned long long int t = s;
      for (int j = 0; j < 13; ++j) {
        int b = t % 13;
        if (b == 0)
          pos[a++] = 12 - j;
        t /= 13;
      }
      for (int j = 0; j < 2; ++j) {
        int b = pos[j];
        for (int k = 0; k < 4; ++k) {
          int c = side[b][k];
          if (c == -1)
            continue;
          t = slide(s, b, c);
          if (ans.find(t) == ans.end()) {
            ans[t] = cnt;
            q.push(t);
          }
        }
      }
    }
    ++cnt;
  }
  while (!q.empty()) {
    s = q.front();
    q.pop();
    ans[s] = 20;
  }

  while (cin >> p[0] && p[0] != -1) {
    for (int i = 1; i < 13; ++i) {
      cin >> p[i];
    }
    s = makeID(p);
    if (ans.find(s) != ans.end()) {
      cout << ans[s] << endl;
    } else {
      cout << "NA" << endl;
    }
  }

  return 0;
}