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

#include <bits/stdc++.h>
using namespace std;
#define FOR(i, k, n) for (int i = (int)(k); i < (int)(n); i++)
#define REP(i, n) FOR(i, 0, n)
#define ALL(a) a.begin(), a.end()
#define MS(m, v) memset(m, v, sizeof(m))
#define D10 fixed << setprecision(10)
typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int, int> pii;
const int MOD = 1000000007;
const int INF = MOD + 1;
const ld EPS = 1e-12;
template <class T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template <class T> T &chmax(T &a, const T &b) { return a = max(a, b); }

/*--------------------template--------------------*/
const int dx[] = {-1, 0, 0, 1}, dy[] = {0, -1, 1, 0};
//[const int dx[] = { -1, -1, -1, 0, 0, 1, 1, 1 }, dy[] = { 0, -1, 1, -1, 1, 0,
//-1, 1 };
bool valid(int x, int y, int h, int w) {
  return (x >= 0 && y >= 0 && x < h && y < w);
}
int place(int x, int y, int w) { return w * x + y; }

typedef vector<vi> mat;
mat fld;
int h, w;

int check(int x, int y) {
  int a = fld[x][y];
  int b = fld[x + 1][y];
  int c = fld[x][y + 1];
  int d = fld[x + 1][y + 1];
  if (a == -1 || b == -1 || c == -1 || d == -1)
    return 1;
  if (a != b && a != c && a != d && b != c && b != d && c != d)
    return 0;
  return 1;
}

int cnt = 0;
void solve(int p) {
  int x = p / w, y = p % w;
  if (p == h * w)
    cnt++;
  else if (fld[x][y] != -1)
    solve(p + 1);
  else {
    fld[x][y] = p;
    if (x != h - 1 && fld[x + 1][y] == -1) {
      fld[x + 1][y] = p;
      if ((x > 0 && y > 0 && check(x - 1, y - 1) && check(x, y - 1)) ||
          (x == 0 || y == 0))
        solve(p + 1);
      fld[x + 1][y] = -1;
    }
    if (y != w - 1 && fld[x][y + 1] == -1) {
      fld[x][y + 1] = p;
      if ((x > 0 && y > 0 && check(x - 1, y - 1) && check(x - 1, y)) ||
          (x == 0 || y == 0))
        solve(p + 1);
      fld[x][y + 1] = -1;
    }
    fld[x][y] = -1;
  }
}

int main() {
  while (cin >> h >> w, h) {
    fld.clear();
    fld.resize(h, vi(w, -1));
    queue<pair<mat, int>> que;
    que.push(make_pair(fld, 0));
    cnt = 0;
    solve(0);
    cout << cnt << endl;
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
#define FOR(i, k, n) for (int i = (int)(k); i < (int)(n); i++)
#define REP(i, n) FOR(i, 0, n)
#define ALL(a) a.begin(), a.end()
#define MS(m, v) memset(m, v, sizeof(m))
#define D10 fixed << setprecision(10)
typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int, int> pii;
const int MOD = 1000000007;
const int INF = MOD + 1;
const ld EPS = 1e-12;
template <class T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template <class T> T &chmax(T &a, const T &b) { return a = max(a, b); }

/*--------------------template--------------------*/
const int dx[] = {-1, 0, 0, 1}, dy[] = {0, -1, 1, 0};
//[const int dx[] = { -1, -1, -1, 0, 0, 1, 1, 1 }, dy[] = { 0, -1, 1, -1, 1, 0,
//-1, 1 };
bool valid(int x, int y, int h, int w) {
  return (x >= 0 && y >= 0 && x < h && y < w);
}
int place(int x, int y, int w) { return w * x + y; }

typedef vector<vi> mat;
mat fld;
int h, w;

int check() {
  REP(i, h - 1) REP(j, w - 1) {
    set<int> st;
    st.insert(fld[i][j]);
    st.insert(fld[i + 1][j]);
    st.insert(fld[i][j + 1]);
    st.insert(fld[i + 1][j + 1]);
    if (st.size() == 4)
      return 0;
  }
  return 1;
}

int cnt = 0;
void solve(int p) {
  int x = p / w, y = p % w;
  if (p == h * w)
    cnt += check();
  else if (fld[x][y] != -1)
    solve(p + 1);
  else {
    fld[x][y] = p;
    if (x != h - 1 && fld[x + 1][y] == -1) {
      fld[x + 1][y] = p;
      solve(p + 1);
      fld[x + 1][y] = -1;
    }
    if (y != w - 1 && fld[x][y + 1] == -1) {
      fld[x][y + 1] = p;
      solve(p + 1);
      fld[x][y + 1] = -1;
    }
    fld[x][y] = -1;
  }
}

int main() {
  while (cin >> h >> w, h) {
    fld.resize(h, vi(w, -1));
    queue<pair<mat, int>> que;
    que.push(make_pair(fld, 0));
    cnt = 0;
    solve(0);
    cout << cnt << endl;
  }

  return 0;
}