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

#include <algorithm>
#include <cassert>
#include <cctype>
#include <cfloat>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
// #include <unordered_map>
using namespace std;
typedef long long LL;
typedef pair<char, int> P;

int n, m;
int table[10][10];
int search(int i, int j, int done) {
  int ret = 0;
  int dx = 1;
  int dy = 0;
  for (int k = 0; k < 4; k++, swap(dx, dy), dx = -dx) {
    int x = i + dx;
    int y = j + dy;
    while (0 <= x && x < n && 0 <= y && y < m) {
      if (table[x][y] >= 0) {
        if (done & (1 << table[x][y])) {
          ret += search(x, y, done ^ (1 << table[x][y]));
          break;
        }
      } else if (done == 0 && table[x][y] == -1) {
        ret++;
        break;
      }
      x += dx;
      y += dy;
    }
  }
  return ret;
}
int main() {
  while (1) {
    cin >> m >> n;
    if (m == 0)
      return 0;
    int s = 0, t = 0;
    int c = 0;
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) {
        int v;
        cin >> v;
        if (v == 1) {
          table[i][j] = c++;
        } else if (v == 2) {
          s = i;
          t = j;
          table[i][j] = -1;
        } else {
          table[i][j] = -2;
        }
      }
    }
    int ret = search(s, t, (1 << c) - 1);
    cout << ret << endl;
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cctype>
#include <cfloat>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <unordered_map>
#include <vector>
using namespace std;
typedef long long LL;
typedef pair<char, int> P;

int n, m;
int table[10][10];
int goal[10][10];
int gs[23];
const int K = 16;
// int memo[1<<K][23];
unordered_map<int, int> memo2[23];
int half;
int target;
int ng;
int ngs[23];
int hx[23];
int hy[23];
int c;
int search(int i, int j, int done) {
  if (done == target) {
    // cout << done << ", " << i << ", " << j << ": " << goal[i][j] << endl;
    return goal[i][j];
  }
  if ((done & ng) == ng) {
    return 0;
  }
  /*
  if(done<(1<<K)&&table[i][j]>=0&&memo[done][table[i][j]]!=-1){
          //cout << done << ", " << i << ", " << j << ": " <<
  memo[done][table[i][j]] << endl; return memo[done][table[i][j]];
  }*/
  if (done % 11 == 0 && table[i][j] >= 0 &&
      memo2[table[i][j]].find(done) != memo2[table[i][j]].end()) {
    return memo2[table[i][j]][done];
  }
  if (table[i][j] >= 0) {
    for (int a = 0; a < c; a++) {
      if (gs[a] == 0 && (done & (1 << a)) == 0) {
        if ((ngs[a] & done) == ngs[a]) {
          /*
          if(done<(1<<K)&&table[i][j]>=0){
                  memo[done][table[i][j]]=0;
          }*/
          /*
          if(table[i][j]>=0){
                  memo2[table[i][j]][done]=0;
          }*/
          return 0;
        }
      }
    }
  }
  int dx = 1;
  int dy = 0;
  int ret = 0;
  for (int k = 0; k < 4; k++, swap(dx, dy), dx = -dx) {
    int x = i + dx;
    int y = j + dy;
    while (0 <= x && x < n && 0 <= y && y < m) {
      if (table[x][y] >= 0) {
        if (!(done & (1 << table[x][y]))) {
          // cout << (done|(1<<table[x][y])) << ": " << done << ", " <<
          // table[x][y] << endl;
          ret += search(x, y, done | (1 << table[x][y]));
        } else {
          break;
        }
      }
      x += dx;
      y += dy;
    }
  }
  /*
  if(done<(1<<K)&&table[i][j]>=0){
          memo[done][table[i][j]]=ret;
  }*/
  if (table[i][j] >= 0 && done % 7 == 0) {
    memo2[table[i][j]][done] = ret;
  }
  return ret;
}
int main() {
  while (1) {
    cin >> m >> n;
    if (m == 0)
      return 0;
    int s = 0, t = 0;
    c = 0;
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) {
        int v;
        cin >> v;
        if (v == 1) {
          hx[c] = i;
          hy[c] = j;
          table[i][j] = c++;
          // cout << i << ", " << j << ": " << table[i][j] << endl;
        } else if (v == 2) {
          s = i;
          t = j;
          table[i][j] = -1;
        } else {
          table[i][j] = -1;
        }
      }
    }
    // memset(memo,-1,sizeof(int)*(23*(1<<min(c,K))));
    memset(goal, 0, sizeof(goal));
    target = (1 << c) - 1;
    int dx = 1;
    int dy = 0;
    ng = 0;
    for (int k = 0; k < 4; k++, swap(dx, dy), dx = -dx) {
      int x = s + dx;
      int y = t + dy;
      while (0 <= x && x < n && 0 <= y && y < m) {
        if (table[x][y] >= 0) {
          goal[x][y] = 1;
          gs[table[x][y]] = 1;
          ng |= (1 << table[x][y]);
          // cout << "goal " << x << ", " << y << endl;
          break;
        }
        x += dx;
        y += dy;
      }
    }

    memset(ngs, 0, sizeof(ngs));
    for (int i = 0; i < c; i++)
      for (int k = 0; k < 4; k++, swap(dx, dy), dx = -dx) {
        int x = hx[i] + dx;
        int y = hy[i] + dy;
        while (0 <= x && x < n && 0 <= y && y < m) {
          if (table[x][y] >= 0) {
            ngs[i] |= (1 << table[x][y]);
            // cout << "goal " << x << ", " << y << endl;
            break;
          }
          x += dx;
          y += dy;
        }
      }
    int ret = search(s, t, 0);
    for (int i = 0; i < c; i++) {
      memo2[i].clear();
    }
    cout << ret << endl;
  }
}