Problem p00471 (C++)

Buggy submission (status: Memory Limit Exceeded):
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

#define EPS 1e-9
#define INF 1070000000LL
#define MOD 1000000007LL
#define fir first
#define foreach(it, X)                                                         \
  for (__typeof((X).begin()) it = (X).begin(); it != (X).end(); it++)
#define ite iterator
#define mp make_pair
#define rep(i, n) rep2(i, 0, n)
#define rep2(i, m, n) for (int i = m; i < (n); i++)
#define pb push_back
#define sec second
#define sz(x) ((int)x.size())

using namespace std;

typedef istringstream iss;
typedef long long ll;
typedef pair<int, int> pi;
typedef stringstream sst;
typedef vector<int> vi;

int m, n, a[111][111];
int h, Y[30], X[30];
int dy[] = {0, 1, 0, -1};
int dx[] = {1, 0, -1, 0};

map<int, int> M;

const int LIM = 16;

int f(int cur, int mask) {
  if (__builtin_popcount(mask) <= LIM) {
    if (M.find(cur << 24 | mask) != M.end())
      return M[cur << 24 | mask];
  }
  int res = 0;
  rep(d, 4) {
    int y = Y[cur], x = X[cur];
    while (1) {
      y += dy[d];
      x += dx[d];
      if (y < 0 || y >= n || x < 0 || x >= m)
        break;
      if (a[y][x] == 0) {
        if (mask == (1 << h) - 2)
          res++;
      }
      if (a[y][x] >= 1) {
        if ((mask >> a[y][x] & 1) == 0) {
          res += f(a[y][x], mask | 1 << a[y][x]);
          break;
        }
      }
    }
  }
  if (__builtin_popcount(mask) <= LIM) {
    M[cur << 24 | mask] = res;
  }
  return res;
}

int main() {
  cin.tie(0);
  ios_base::sync_with_stdio(0);
  while (cin >> m >> n && m) {
    M.clear();
    h = 1;
    rep(i, n) rep(j, m) {
      cin >> a[i][j];
      if (a[i][j] == 0) {
        a[i][j] = -1;
      } else if (a[i][j] == 1) {
        Y[h] = i, X[h] = j;
        a[i][j] = h++;
      } else {
        Y[0] = i, X[0] = j;
        a[i][j] = 0;
      }
    }
    cout << f(0, 0) << endl;
  }
}

Fixed submission:
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

#define EPS 1e-9
#define INF 1070000000LL
#define MOD 1000000007LL
#define fir first
#define foreach(it, X)                                                         \
  for (__typeof((X).begin()) it = (X).begin(); it != (X).end(); it++)
#define ite iterator
#define mp make_pair
#define rep(i, n) rep2(i, 0, n)
#define rep2(i, m, n) for (int i = m; i < (n); i++)
#define pb push_back
#define sec second
#define sz(x) ((int)x.size())

using namespace std;

typedef istringstream iss;
typedef long long ll;
typedef pair<int, int> pi;
typedef stringstream sst;
typedef vector<int> vi;

int m, n, a[111][111];
int h, Y[30], X[30];
int dy[] = {0, 1, 0, -1};
int dx[] = {1, 0, -1, 0};

map<int, int> M;

const int LIM = 15;

int f(int cur, int mask) {
  if (__builtin_popcount(mask) <= LIM) {
    if (M.find(cur << 24 | mask) != M.end())
      return M[cur << 24 | mask];
  }
  int res = 0;
  rep(d, 4) {
    int y = Y[cur], x = X[cur];
    while (1) {
      y += dy[d];
      x += dx[d];
      if (y < 0 || y >= n || x < 0 || x >= m)
        break;
      if (a[y][x] == 0) {
        if (mask == (1 << h) - 2)
          res++;
      }
      if (a[y][x] >= 1) {
        if ((mask >> a[y][x] & 1) == 0) {
          res += f(a[y][x], mask | 1 << a[y][x]);
          break;
        }
      }
    }
  }
  if (__builtin_popcount(mask) <= LIM) {
    M[cur << 24 | mask] = res;
  }
  return res;
}

int main() {
  cin.tie(0);
  ios_base::sync_with_stdio(0);
  while (cin >> m >> n && m) {
    M.clear();
    h = 1;
    rep(i, n) rep(j, m) {
      cin >> a[i][j];
      if (a[i][j] == 0) {
        a[i][j] = -1;
      } else if (a[i][j] == 1) {
        Y[h] = i, X[h] = j;
        a[i][j] = h++;
      } else {
        Y[0] = i, X[0] = j;
        a[i][j] = 0;
      }
    }
    cout << f(0, 0) << endl;
  }
}