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

#include <iostream>
#include <map>
#include <queue>
#include <tuple>
#include <vector>

using namespace std;

class range {
private:
  struct Iterator {
    int val;
    int operator*() { return val; }
    bool operator!=(Iterator &itr) { return val < itr.val; }
    void operator++() { ++val; }
  };
  Iterator i, n;

public:
  range(int n) : i({0}), n({n}) {}
  range(int i, int n) : i({i}), n({n}) {}
  Iterator &begin() { return i; }
  Iterator &end() { return n; }
};

template <class T> T at(vector<T> v, int i) {
  return v[(i % (int)v.size() + v.size()) % v.size()];
}

const int dx[] = {1, 0, -1, 0};
const int dy[] = {0, -1, 0, 1};

int main() {
  while (true) {
    int m, n;
    cin >> m >> n;
    if (m == 0 && n == 0)
      break;
    int p[n][m];
    for (int i : range(n))
      for (int j : range(m))
        cin >> p[i][j];
    vector<pair<int, int>> house;
    for (int i : range(n))
      for (int j : range(m))
        if (p[i][j] == 1)
          house.emplace_back(i, j);
    int s[n][m];
    for (int i : range(n))
      for (int j : range(m))
        s[i][j] = -1;
    for (int i : range(house.size()))
      s[house[i].first][house[i].second] = i;
    queue<tuple<int, int, int>> que;
    for (int i : range(n))
      for (int j : range(m))
        if (p[i][j] == 2)
          que.push(make_tuple(i, j, (1 << house.size()) - 1));
    int res = 0;
    map<tuple<int, int, int>, int> mp;
    ++mp[que.front()];
    while (!que.empty()) {
      auto now = que.front();
      que.pop();
      int y = get<0>(now);
      int x = get<1>(now);
      int bit = get<2>(now);
      // cerr << y << " " << x << " ";
      // for (int i : range(7)) cerr << (bit >> i & 1);
      // cerr << " " << mp[now] << endl;
      for (int i : range(4)) {
        int yy = y + dy[i];
        int xx = x + dx[i];
        while (true) {
          if (yy < 0 || n <= yy)
            break;
          if (xx < 0 || m <= xx)
            break;
          if (p[yy][xx] == 1 && (bit & 1 << s[yy][xx])) {
            auto t = make_tuple(yy, xx, bit ^ 1 << s[yy][xx]);
            if (!mp.count(t))
              que.push(t);
            mp[t] += mp[now];
            break;
          }
          if (p[yy][xx] == 2 && bit == 0)
            res += mp[now];
          yy += dy[i];
          xx += dx[i];
        }
      }
      mp.erase(now);
    }
    cout << res << endl;
  }
}

Error: MLE

Fixed submission:

#include <iostream>
#include <map>
#include <queue>
#include <tuple>
#include <vector>

using namespace std;

class range {
private:
  struct Iterator {
    int val;
    int operator*() { return val; }
    bool operator!=(Iterator &itr) { return val < itr.val; }
    void operator++() { ++val; }
  };
  Iterator i, n;

public:
  range(int n) : i({0}), n({n}) {}
  range(int i, int n) : i({i}), n({n}) {}
  Iterator &begin() { return i; }
  Iterator &end() { return n; }
};

template <class T> T at(vector<T> v, int i) {
  return v[(i % (int)v.size() + v.size()) % v.size()];
}

const int dx[] = {1, 0, -1, 0};
const int dy[] = {0, -1, 0, 1};

int main() {
  while (true) {
    int m, n;
    cin >> m >> n;
    if (m == 0 && n == 0)
      break;
    int p[n][m];
    for (int i : range(n))
      for (int j : range(m))
        cin >> p[i][j];
    vector<pair<int, int>> house;
    for (int i : range(n))
      for (int j : range(m))
        if (p[i][j] == 1)
          house.emplace_back(i, j);
    int s[n][m];
    for (int i : range(n))
      for (int j : range(m))
        s[i][j] = -1;
    for (int i : range(house.size()))
      s[house[i].first][house[i].second] = i;
    queue<tuple<int, int, int>> que;
    for (int i : range(n))
      for (int j : range(m))
        if (p[i][j] == 2)
          que.push(make_tuple(i, j, (1 << house.size()) - 1));
    int res = 0;
    map<tuple<int, int, int>, int> mp;
    ++mp[que.front()];
    while (!que.empty()) {
      auto now = que.front();
      que.pop();
      int y = get<0>(now);
      int x = get<1>(now);
      int bit = get<2>(now);
      // cerr << y << " " << x << " ";
      // for (int i : range(7)) cerr << (bit >> i & 1);
      // cerr << " " << mp[now] << endl;
      for (int i : range(4)) {
        int yy = y + dy[i];
        int xx = x + dx[i];
        while (true) {
          if (yy < 0 || n <= yy)
            break;
          if (xx < 0 || m <= xx)
            break;
          if (p[yy][xx] == 1 && (bit & 1 << s[yy][xx])) {
            auto t = make_tuple(yy, xx, bit ^ 1 << s[yy][xx]);
            if (!mp.count(t))
              que.push(t);
            mp[t] += mp[now];
            break;
          }
          if (p[yy][xx] == 2 && bit == 0)
            res += mp[now];
          yy += dy[i];
          xx += dx[i];
        }
      }
    }
    cout << res << endl;
  }
}