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

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

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

using namespace std;

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

int n;
bool market[365][16];
bool V[366][2401][9];

bool check(int day, int y, int x) {
  rep(i, 2) rep(j, 2) if (market[day][(y + i) * 4 + x + j]) return 0;
  return 1;
}
bool visit(int day, int y, int x, int r0, int r1, int r2, int r3) {
  bool &v = V[day][343 * r0 + 49 * r1 + 7 * r2 + r3][y * 3 + x];
  if (v)
    return 1;

  v = 1;
  return 0;
}
bool dfs(int day, int cy, int cx, int r0, int r1, int r2, int r3) {
  if (day >= n)
    return 1;

  for (int ny = cy - 2; ny <= cy + 2; ny++)
    for (int nx = cx - 2; nx <= cx + 2; nx++)
      if (ny == cy || nx == cx)
        if (0 <= ny && ny < 3 && 0 <= nx && nx < 3) {
          if (!check(day, ny, nx))
            continue;
          int nr0 = r0, nr1 = r1, nr2 = r2, nr3 = r3;
          if (ny == 0 && nx == 0)
            nr0 = 0;
          else
            nr0++;
          if (ny == 0 && nx == 2)
            nr1 = 0;
          else
            nr1++;
          if (ny == 2 && nx == 0)
            nr2 = 0;
          else
            nr2++;
          if (ny == 2 && nx == 2)
            nr3 = 0;
          else
            nr3++;

          if (nr0 >= 7 || nr1 >= 7 || nr2 >= 7 || nr3 >= 7)
            continue;
          if (visit(day + 1, ny, nx, nr0, nr1, nr2, nr3))
            continue;
          if (dfs(day + 1, ny, nx, nr0, nr1, nr2, nr3))
            return 1;
        }
  return 0;
}
int main() {
  while (scanf("%d", &n), n) {
    rep(i, n) rep(j, 16) scanf("%d", market[i] + j);
    rep(i, n + 1) rep(j, 2401) fill_n(V[i][j], 9, 0);

    if (!check(0, 1, 1)) {
      cout << 0 << endl;
      continue;
    }
    cout << dfs(1, 1, 1, 1, 1, 1, 1) << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

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

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

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pi;
const int inf = 1 << 28;
const double INF = 1e10, EPS = 1e-9;

struct Node {
  int d, cy, cx, f[4];
  bool operator<(const Node &r) const {
    if (d != r.d)
      return d < r.d;
    if (cy != r.cy)
      return cy < r.cy;
    if (cx != r.cx)
      return cx < r.cx;
    rep(i, 4) if (f[i] != r.f[i]) return f[i] < r.f[i];
    return 0;
  }
  Node(int d_, int y, int x, int *f_) {
    d = d_, cy = y, cx = x;
    rep(i, 4) f[i] = f_[i];
  }
};

int d;
bool m[365][4][4];
int f[4];
set<Node> V;

bool solve(int now, int cy, int cx) {
  if (V.count(Node(now, cy, cx, f)))
    return 0;
  rep(i, 2) rep(j, 2) if (m[now][cy + i][cx + j]) return 0;
  rep(i, 4) {
    int y = (i << 1) ? 0 : 3, x = (i & 1) ? 0 : 3;
    if (cy <= y && y <= cy + 1 && cx <= x && x <= cx + 1)
      f[i] = -1;
  }
  rep(i, 4) if (++f[i] > 6) return 0;

  if (++now == d)
    return 1;
  V.insert(Node(now, cy, cx, f));

  for (int y = cy - 2; y <= cy + 2; y++)
    for (int x = cx - 2; x <= cx + 2; x++)
      if (y == cy || x == cx) {
        if (y < 0 || x < 0 || y >= 4 || x >= 4)
          continue; // invalid move

        int tmp[4];
        rep(j, 4) tmp[j] = f[j];
        if (solve(now, y, x))
          return 1;
        rep(j, 4) f[j] = tmp[j];
      }
  return 0;
}

int main() {
  while (cin >> d, d) {
    rep(i, d) rep(j, 4) rep(k, 4) cin >> m[i][j][k];
    fill(f, f + 4, 0);
    V.clear();

    cout << solve(0, 1, 1) << endl;
  }
  return 0;
}