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

#include <bits/stdc++.h>

using namespace std;

#define int long long
#define PB push_back
#define ALL(V) V.begin(), V.end()
typedef pair<int, int> pii;
typedef pair<int, pii> pipii;
typedef pair<pii, pii> pipi;

constexpr int INF = 1LL << 60;
constexpr int MOD = 1000000007;
constexpr int MAX_N = 11;
constexpr int dx[] = {-1, 0, 1, 0};
constexpr int dy[] = {0, -1, 0, 1};

int fld[MAX_N][MAX_N], w, h, sx, sy, idx;
int hoge;

int Solve(int x, int y, int mask) {
  if (x == sx && y == sy) {
    if (mask)
      return 0;
    return 1;
  }

  int res = 0;
  for (int i = 0; i < 4; ++i) {
    int tx = x, ty = y;
    while (0 < tx && 0 < ty && tx <= w && ty <= h) {
      tx += dx[i];
      ty += dy[i];
      if (sx == tx && sy == ty)
        res += Solve(tx, ty, mask);

      int num = fld[tx][ty];
      if (num == -1)
        continue;
      if (mask & (1 << num)) {
        res += Solve(tx, ty, mask - (1 << num));
        break;
      }
    }
  }

  return res;
}

signed main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);

  while (cin >> w >> h, w) {
    memset(fld, -1, sizeof(fld));
    idx = 0;

    for (int y = 1; y <= h; ++y) {
      for (int x = 1; x <= w; ++x) {
        int t;
        cin >> t;
        if (t == 0)
          continue;
        if (t == 2) {
          sx = x;
          sy = y;
          continue;
        } else
          t = idx++;
        fld[x][y] = t;
      }
    }

    int ans = 0;
    for (int i = 0; i < 4; ++i) {
      int tx = sx, ty = sy;
      while (0 < tx && tx <= w && 0 < ty && ty <= h) {
        tx += dx[i];
        ty += dy[i];
        if (fld[tx][ty] == -1)
          continue;
        ans += Solve(tx, ty, (1 << idx) - 1 - (1 << fld[tx][ty]));
        break;
      }
    }
    cout << ans << endl;
  }
}

Error: MLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

// #define int long long
#define PB push_back
#define MK make_pair
#define MKT make_tuple
#define ALL(V) V.begin(), V.end()
typedef pair<int, int> pii;
typedef pair<int, pii> pipii;
typedef pair<pii, pii> pipi;

// constexpr int INF = 1LL<<60;
constexpr int INF = 1 << 28;
constexpr int MOD = 1000000007;
constexpr int MAX_N = 23;
constexpr int dx[] = {-1, 0, 1, 0};
constexpr int dy[] = {0, -1, 0, 1};

map<pii, int> mem;
int w, h, sx, sy;
vector<pii> hs, xl, yl;
vector<tuple<int, int, int>> xy, yx;

int Solve(int k, int mask) {
  if (k == hs.size()) {
    if (mask == (1 << (hs.size() + 1)) - 1 && k == hs.size()) {
      return 1;
    }
    return 0;
  }
  if (mem.find({k, mask}) != mem.end())
    return mem[{k, mask}];

  int res = 0, x = hs[k].first, y = hs[k].second;
  auto st = lower_bound(ALL(xy), MKT(x, y, k));
  for (auto it = st + 1; it != xy.end() && get<0>(*it) == x; ++it) {
    int tk = get<2>(*it);
    if (mask & (1 << tk))
      break;
    res += Solve(tk, mask + (1 << tk));
  }
  for (auto it = st - 1; xy.begin() <= it && get<0>(*it) == x; --it) {
    int tk = get<2>(*it);
    if (mask & (1 << tk))
      break;
    res += Solve(tk, mask + (1 << tk));
  }

  st = lower_bound(ALL(yx), MKT(y, x, k));
  for (auto it = st + 1; it != yx.end() && get<0>(*it) == y; ++it) {
    int tk = get<2>(*it);
    if (mask & (1 << tk))
      break;
    res += Solve(tk, mask + (1 << tk));
  }
  for (auto it = st - 1; yx.begin() <= it && get<0>(*it) == y; --it) {
    int tk = get<2>(*it);
    if (mask & (1 << tk))
      break;
    res += Solve(tk, mask + (1 << tk));
  }

  mem.insert({{k, mask}, res});
  return res;
}

signed main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);

  while (cin >> w >> h, w) {
    mem.clear();
    xy.clear();
    yx.clear();
    hs.clear();

    for (int y = 1; y <= h; ++y) {
      for (int x = 1; x <= w; ++x) {
        int t;
        cin >> t;
        if (t == 1) {
          xy.PB(MKT(x, y, hs.size()));
          yx.PB(MKT(y, x, hs.size()));
          hs.PB({x, y});
        } else if (t == 2) {
          sx = x;
          sy = y;
        }
      }
    }

    xy.PB(MKT(sx, sy, hs.size()));
    yx.PB(MKT(sy, sx, hs.size()));
    sort(ALL(xy));
    sort(ALL(yx));

    int ans = 0;
    auto st = lower_bound(ALL(xy), MKT(sx, -INF, -INF));
    for (auto it = st; it != xy.end() && get<0>(*it) == sx; ++it) {
      int tk = get<2>(*it);
      if (tk == hs.size())
        continue;
      ans += Solve(tk, 1 << tk);
    }

    st = lower_bound(ALL(yx), MKT(sy, -INF, -INF));
    for (auto it = st; it != yx.end() && get<0>(*it) == sy; ++it) {
      int tk = get<2>(*it);
      if (tk == hs.size())
        continue;
      ans += Solve(tk, 1 << tk);
    }
    cout << ans << endl;
  }
}