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

#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <set>
#include <sstream>
#include <vector>

using namespace std;

#define rep(i, n) for (int i = 0; i < n; i++)
#define fr(i, c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); i++)
#define pb push_back
#define mp make_pair
typedef long long ll;

int dy[] = {-1, 0, 1, 0}, dx[] = {0, -1, 0, 1};
int w, h, sy, sx;
ll goal = 0;

bool v[7][7];
void nul(int y, int x) {
  v[y][x] = 1;
  rep(d, 4) {
    int ny = y + dy[d], nx = x + dx[d];
    if (ny < 0 || nx < 0 || ny >= h || nx >= w || v[ny][nx])
      continue;
    nul(ny, nx);
  }
}
bool separate(ll c) {
  rep(i, h) rep(j, w) v[i][j] = c & 1ll << i * w + j;
  int cnt = 0;
  rep(i, h) rep(j, w) if (!v[i][j]) {
    if (cnt++ > 0)
      return 1;
    nul(i, j);
  }
  return 0;
}
const int sz = 1000003;
ll hash[sz];
bool ins(ll v) {
  ll h = v % sz;
  for (; hash[h] != ~0ll; h = (h + 1) % sz)
    if (hash[h] == v)
      return 1;
  hash[h] = v;
  return 0;
}

bool rec(int y, int x, ll c) {
  if (ins(c << 6 | y << 3 | x))
    return 0;

  rep(d, 4) {
    int ny = y + dy[d], nx = x + dx[d];
    if (ny < 0 || nx < 0 || ny >= h || nx >= w || (c & 1ll << ny * w + nx))
      continue;
    ll nc = c | 1ll << ny * w + nx;

    if (nc == goal && ny == sy && nx == sx)
      return 1;
    if (!separate(nc) && rec(ny, nx, nc))
      return 1;
  }
  return 0;
}
int main() {
  while (cin >> w >> h, w) {
    sy = -1;
    sx = -1;
    ll c = 0;
    int t;
    rep(i, h) rep(j, w) {
      cin >> t;
      if (t)
        c ^= 1ll << i * w + j;
    }
    goal = (1ll << h * w) - 1;

    if (h > 4 && w > 4 && c == 0) {
      if (h % 2 && w % 2)
        cout << "No" << endl;
      else
        cout << "Yes" << endl;
      continue;
    }
    rep(i, h) rep(j, w) if (!(c & 1ll << i * w + j)) {
      int cnt = 0;
      rep(d, 4) {
        int ny = i + dy[d], nx = j + dx[d];
        if (ny < 0 || nx < 0 || ny >= h || nx >= w || (c & 1ll << ny * w + nx))
          cnt++;
      }
      if (cnt > 2)
        goto OUT;
    }

    rep(i, h)
        rep(j, w - 1) if ((c & 1ll << i * w + j) + (c & 1ll << i * w + j + 1) ==
                          0) {
      sy = i;
      sx = j;
      goto OUT;
    }
  OUT:
    if (sy < 0) {
      cout << "No" << endl;
      continue;
    }
    rep(i, sz) hash[i] = ~0ll;
    cout << (rec(sy, sx, c) ? "Yes" : "No") << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <set>
#include <sstream>
#include <vector>

using namespace std;

#define rep(i, n) for (int i = 0; i < n; i++)
#define fr(i, c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); i++)
#define pb push_back
#define mp make_pair
typedef long long ll;

int dy[] = {-1, 0, 1, 0}, dx[] = {0, -1, 0, 1};
int w, h, sy, sx;
ll goal = 0;

bool v[7][7];
void nul(int y, int x) {
  v[y][x] = 1;
  rep(d, 4) {
    int ny = y + dy[d], nx = x + dx[d];
    if (ny < 0 || nx < 0 || ny >= h || nx >= w || v[ny][nx])
      continue;
    nul(ny, nx);
  }
}
bool separate(ll c) {
  rep(i, h) rep(j, w) v[i][j] = c & 1ll << i * w + j;
  int cnt = 0;
  rep(i, h) rep(j, w) if (!v[i][j]) {
    if (cnt++ > 0)
      return 1;
    nul(i, j);
  }
  return 0;
}
set<ll> M;
bool rec(int y, int x, ll c) {
  if (M.count(c << 6 | y << 3 | x))
    return 0;
  M.insert(c << 6 | y << 3 | x);

  rep(d, 4) {
    int ny = y + dy[d], nx = x + dx[d];
    if (ny < 0 || nx < 0 || ny >= h || nx >= w || (c & 1ll << ny * w + nx))
      continue;
    ll nc = c | 1ll << ny * w + nx;

    if (nc == goal && ny == sy && nx == sx)
      return 1;
    if (!separate(nc) && rec(ny, nx, nc))
      return 1;
  }
  return 0;
}
int main() {
  while (cin >> w >> h, w) {
    sy = -1;
    sx = -1;
    ll c = 0;
    int t;
    rep(i, h) rep(j, w) {
      cin >> t;
      if (t)
        c ^= 1ll << i * w + j;
    }
    goal = (1ll << h * w) - 1;

    if (h > 4 && w > 4 && c == 0) {
      if (h % 2 && w % 2)
        cout << "No" << endl;
      else
        cout << "Yes" << endl;
      continue;
    }
    rep(i, h) rep(j, w) if (!(c & 1ll << i * w + j)) {
      int cnt = 0;
      rep(d, 4) {
        int ny = i + dy[d], nx = j + dx[d];
        if (ny < 0 || nx < 0 || ny >= h || nx >= w || (c & 1ll << ny * w + nx))
          cnt++;
      }
      if (cnt > 2) {
        cerr << i << " " << j << endl;
        goto OUT;
      }
    }

    rep(i, h)
        rep(j, w - 1) if ((c & 1ll << i * w + j) + (c & 1ll << i * w + j + 1) ==
                          0) {
      sy = i;
      sx = j;
      goto OUT;
    }
  OUT:
    if (sy < 0) {
      cout << "No" << endl;
      continue;
    }
    M.clear();
    cout << (rec(sy, sx, c) ? "Yes" : "No") << endl;
  }
  return 0;
}