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

#include <cstdio>
#include <map>
using namespace std;
int mp[144], m, n, hs, ch;
int dir[] = {-12, -1, 1, 12};
map<int, int> memo;
int func(int p, int d, int u) {
  while (1) {
    int h = mp[p];
    if (h >= 0) {
      int s = 0;
      mp[p] = -1;
      hs ^= 1 << h;
      if (u > 12) {
        for (int i = 0; i < 4; i++)
          s += func(p + dir[i], dir[i], u - 1);
      } else {
        int mi = h << 23 | hs;
        map<int, int>::iterator it = memo.find(mi);
        if (it == memo.end()) {
          for (int i = 0; i < 4; i++)
            s += func(p + dir[i], dir[i], u - 1);
          memo[mi] = s;
        } else {
          s = it->second;
        }
      }
      hs |= 1 << h;
      mp[p] = h;
      return s;
    }
    if (h == -9)
      break;
    p += d;
  }
  return 0;
}
int main() {
  int i, j, p, t;
  for (; scanf("%d%d", &m, &n), m; memo.clear()) {
    hs = 0;
    for (i = 0; i < 144; i++)
      mp[i] = -9;
    for (i = 1; i <= n; i++)
      for (j = 1; j <= m; j++) {
        p = i * 12 + j;
        scanf("%d", &t);
        switch (t) {
        case 2:
          ch = p;
        case 0:
          mp[p] = -1;
          break;
        case 1:
          memo[hs << 23] = 0;
          mp[p] = hs++;
          break;
        }
      }
    for (i = 0; i < 4;) {
      t = dir[i++];
      for (j = ch; mp[j += t] != -9; mp[j] >= 0 ? memo[mp[j] << 23] = 1 : 0)
        ;
    }
    j = hs;
    hs = (1 << hs) - 1;
    t = 0;
    for (i = -1; ++i < 4;)
      t += func(ch + dir[i], dir[i], j);
    printf("%d\\n", t);
  }
}

Error: MLE

Fixed submission:

#include <cstdio>
#include <map>
using namespace std;

int mp[144], m, n, hs, ch;
int dir[] = {-12, -1, 1, 12};
map<int, int> memo;

int func(int p, int d, int u) {
  while (1) {
    int h = mp[p];
    if (h >= 0) {
      int s = 0;
      mp[p] = -1;
      hs ^= 1 << h;
      if (u > 13) {
        for (int i = 0; i < 4; i++)
          s += func(p + dir[i], dir[i], u - 1);
      } else {
        int mi = h << 23 | hs;
        map<int, int>::iterator it = memo.find(mi);
        if (it == memo.end()) {
          for (int i = 0; i < 4; i++)
            s += func(p + dir[i], dir[i], u - 1);
          memo[mi] = s;
        } else {
          s = it->second;
        }
      }
      hs |= 1 << h;
      mp[p] = h;
      return s;
    }
    if (h == -9)
      break;
    p += d;
  }
  return 0;
}

int main(void) {
  int i, j, p, t;
  for (; scanf("%d%d", &m, &n), m;) {
    hs = 0;
    memo.clear();
    for (i = 0; i < 144; i++)
      mp[i] = -9;
    for (i = 1; i <= n; i++)
      for (j = 1; j <= m; j++) {
        p = i * 12 + j;
        scanf("%d", &t);
        switch (t) {
        case 2:
          ch = p;
        case 0:
          mp[p] = -1;
          break;
        case 1:
          memo[hs << 23] = 0;
          mp[p] = hs++;
          break;
        }
      }
    for (i = 0; i < 4; i++) {
      t = dir[i];
      for (j = ch; mp[j += t] != -9;)
        if (mp[j] >= 0)
          memo[mp[j] << 23] = 1;
    }
    j = hs;
    hs = (1 << hs) - 1;
    t = 0;
    for (i = 0; i < 4; i++) {
      t += func(ch + dir[i], dir[i], j);
    }
    printf("%d\\n", t);
  }
}