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

#include <algorithm>
#include <cassert>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>

#define rep(i, n) for (int i = 0; i < (int)n; i++)
#define all(c) (c).begin(), (c).end()
#define mp make_pair
#define pb push_back
#define each(i, c)                                                             \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)
#define dbg(x) cerr << __LINE__ << ": " << #x << " = " << (x) << endl

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pi;
const int inf = (int)1e9;
const double INF = 1e12, EPS = 1e-9;

int w, h, in[10][10], tmp[10][10];
inline int f(int y, int x, int d, int dy, int dx) {
  if (d >= 4)
    x = 10 - x - 1, d -= 4;
  if (d == 1)
    swap(y, x), x = 10 - x - 1;
  if (d == 2)
    y = 10 - y - 1, x = 10 - x - 1;
  if (d == 3)
    swap(y, x), y = 10 - y - 1;
  y += dy;
  x += dx;
  if (y < 0 || x < 0 || y >= h || x >= w)
    return -1;
  return y * 10 + x;
}
inline int g(int y, int x, int d, int dy, int dx) {
  y -= dy;
  x -= dx;
  if (d % 4 == 3)
    swap(y, x), x = 10 - x - 1;
  if (d % 4 == 2)
    y = 10 - y - 1, x = 10 - x - 1;
  if (d % 4 == 1)
    swap(y, x), y = 10 - y - 1;
  if (d >= 4)
    x = 10 - x - 1, d -= 4;
  if (y < 0 || x < 0 || y >= h || x >= w)
    return -1;
  return y * 10 + x;
}
void nul(int y, int x) {
  const int dy[] = {-1, 0, 1, 0}, dx[] = {0, -1, 0, 1};
  int prev = tmp[y][x];
  tmp[y][x] = -1;
  rep(d, 4) {
    int ny = y + dy[d], nx = x + dx[d];
    if (ny < 0 || nx < 0 || ny >= h || nx >= w || tmp[ny][nx] != prev)
      continue;
    nul(ny, nx);
  }
}
bool rec(int y, int x, int dy, int dx, int d) {
  if (x == w)
    return rec(y + 1, 0, dy, dx, d);
  if (y == h) {
    bool ok[3] = {};
    rep(i, h) rep(j, w) if (tmp[i][j] > 0) {
      if (!tmp[i][j] || ok[tmp[i][j]])
        return 0;
      ok[tmp[i][j]] = 1;
      nul(i, j);
    }
    return 1;
  }
  if (!in[y][x] || tmp[y][x])
    return rec(y, x + 1, dy, dx, d);

  int t = f(y, x, d, dy, dx);
  if (t != y * 10 + x && t >= 0 && tmp[t / 10][t % 10] == 0 &&
      in[t / 10][t % 10]) {
    tmp[y][x] = 1;
    tmp[t / 10][t % 10] = 2;
    if (rec(y, x + 1, dy, dx, d))
      return 1;
    tmp[y][x] = tmp[t / 10][t % 10] = 0;
  }
  t = g(y, x, d, dy, dx);
  if (t == y * 10 + x || t < 0 || tmp[t / 10][t % 10] != 0 ||
      !in[t / 10][t % 10])
    return 0;
  tmp[y][x] = 2;
  tmp[t / 10][t % 10] = 1;
  return rec(y, x + 1, dy, dx, d);
}

int main() {
  while (cin >> w >> h, w) {
    rep(i, h) rep(j, w) cin >> in[i][j];
    rep(y, 30) rep(x, 30) rep(d, 8) {
      memset(tmp, 0, sizeof(tmp));
      if (rec(0, 0, y - 15, x - 15, d)) {
        cout << "YES" << endl;
        goto END;
      }
    }
    cout << "NO" << endl;
  END:;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <sstream>
#include <vector>
using namespace std;

#define rep(i, n) for (int i = 0; i < (int)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
#define all(c) c.begin(), c.end()
#define dbg(x) cerr << #x << " = " << (x) << endl

typedef vector<int> vi;
typedef pair<int, int> pi;
typedef long long ll;
const int inf = (int)1e9;
const double EPS = 1e-9, INF = 1e12;

const int dy[] = {-1, 0, 1, 0}, dx[] = {0, -1, 0, 1};
int w, h;
int in[10][10];
bool tate[11][11], yoko[11][11];

bool v[10][10];
int a[10], b[10];

int nul(int *a, int y, int x) {
  v[y][x] = 1;
  a[y] |= 1 << x;
  int res = 1;
  rep(d, 4) {
    int ny = y + dy[d], nx = x + dx[d];
    if (!(0 <= ny && ny < h && 0 <= nx && nx < w && !v[ny][nx] && in[ny][nx]))
      continue;
    if (d % 2 == 0 && yoko[max(ny, y)][nx] || d % 2 && tate[y][max(nx, x)])
      continue;
    res += nul(a, ny, nx);
  }
  return res;
}
inline void flip(int *a) {
  rep(i, 10) rep(j, 5) a[i] = (a[i] & ~(1 << j | 1 << 9 - j)) |
                              (a[i] >> j & 1) << 9 - j |
                              (a[i] >> 9 - j & 1) << j;
}
inline void rot(int *a) {
  int b[10];
  rep(i, 10) b[i] = a[i], a[i] = 0;
  rep(i, 10) rep(j, 10) a[i] |= (b[j] >> 9 - i & 1) << j;
}
void normalize(int *a) {
  for (;;) {
    if (a[0])
      goto OUT;
    rep(i, 10) a[i] = i == 9 ? 0 : a[i + 1];
  }
OUT:
  for (;;) {
    rep(i, 10) if (a[i] & 1) return;
    rep(i, 10) a[i] >>= 1;
  }
}

bool ck() {
  int area[2], cnt = 0;
  rep(i, 10) {
    rep(j, 10) v[i][j] = 0;
    a[i] = b[i] = 0;
  }
  rep(i, h) rep(j, w) if (in[i][j] && !v[i][j]) {
    if (cnt > 1)
      return 0;
    area[cnt] = nul(cnt ? b : a, i, j);
    cnt++;
  }
  if (cnt != 2 || area[0] != area[1])
    return 0;
  // rep(i,h+1)rep(j,w)cerr<<yoko[i][j]<<(j==w-1?"\\n":" ");
  // rep(i,h)rep(j,w+1)cerr<<tate[i][j]<<(j==w?"\\n":" ");

  normalize(a);
  rep(i, 4) rep(j, 2) {
    normalize(b);
    rep(k, 10) if (a[k] != b[k]) goto FAIL;
    return 1;
  FAIL:
    flip(b);
    if (j == 1)
      rot(b);
  }
  return 0;
}

bool dfs(int y, int x, int pd) {
  rep(d, 4) if (pd < 0 || d == pd) {
    int ny = y + dy[d], nx = x + dx[d];

    if (ny < 0 || ny >= h + 1 || nx < 0 || nx >= w + 1)
      continue;
    if (d % 2 == 0 && tate[min(ny, y)][x] || d % 2 && yoko[y][min(nx, x)])
      continue;

    if (d % 2 == 0)
      tate[min(ny, y)][x] = 1;
    else
      yoko[y][min(nx, x)] = 1;

    // dbg(ny); dbg(nx); dbg(d);
    if (yoko[ny][nx] + yoko[ny][nx - 1] + tate[ny][nx] + tate[ny - 1][nx] > 1) {
      if (ck())
        return 1;
    } else if (dfs(ny, nx, -1))
      return 1;

    if (d % 2 == 0)
      tate[min(ny, y)][x] = 0;
    else
      yoko[y][min(nx, x)] = 0;
  }
  return 0;
}

int main() {
  while (cin >> w >> h, w) {
    memset(in, 0, sizeof(in));
    memset(tate, 0, sizeof(tate));
    memset(yoko, 0, sizeof(yoko));

    rep(i, h) rep(j, w) cin >> in[i][j];
    rep(i, h) rep(j, w) if (in[i][j]) {
      rep(d, 4) {
        int y = i + dy[d], x = j + dx[d];
        if (y < 0 || y >= h || x < 0 || x >= w || !in[y][x]) {
          if (d % 2 == 0)
            yoko[max(y, i)][j] = 1;
          else
            tate[i][max(x, j)] = 1;
        }
      }
    }

    // rep(i,h+1)rep(j,w)cerr<<yoko[i][j]<<(j==w-1?"\\n":" ");
    // rep(i,h)rep(j,w+1)cerr<<tate[i][j]<<(j==w?"\\n":" ");

    bool ans = 0;
    rep(i, h)
        rep(j, w - 1) if ((i == h - 1 || !in[i + 1][j] || !in[i + 1][j + 1]) &&
                          in[i][j] && in[i][j + 1]) ans |= dfs(i + 1, j + 1, 0);
    rep(i, h - 1)
        rep(j, w) if ((j == w - 1 || !in[i][j + 1] || in[i + 1][j + 1]) &&
                      in[i][j] && in[i + 1][j]) ans |= dfs(i + 1, j + 1, 1);
    rep(i, h)
        rep(j, w - 1) if ((i == 0 || !in[i - 1][j] || !in[i - 1][j + 1]) &&
                          in[i][j] && in[i][j + 1]) ans |= dfs(i, j + 1, 2);
    rep(i, h - 1)
        rep(j, w) if ((j == 0 || !in[i][j - 1] || !in[i + 1][j - 1]) &&
                      in[i][j] && in[i + 1][j]) ans |= dfs(i + 1, j, 3);
    cout << (ans ? "YES" : "NO") << endl;
  }
  return 0;
}