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

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <map>
#include <set>
#include <vector>
using namespace std;

#define REP(i, a, n) for (i = a; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define foreach(it, x)                                                         \\
  for (typeof(x.begin()) it = x.begin(); it != x.end(); it++)

// YET_SYSTEM_TEST

typedef long long ll;

const int dx[] = {0, 1, 0, -1};
const int dy[] = {-1, 0, 1, 0};
int w, h, tatu_x[20], tatu_y[20], kazu_x[20], kazu_y[20];
int field[12][12], cx[36], cy[36], csize;
map<pair<int, int>, int> idx;
set<pair<ll, ll>> visited[20][4][2];

bool inside(int x, int y) { return !(x < 0 || x >= w || y >= h || y < 0); }

bool backtrack(int cnt, ll tS, ll kS, int init_dir, int f) {
  int i, j, k;

  if (visited[cnt][init_dir][f].count(make_pair(tS, kS)))
    return false;
  if (csize / 2 == cnt)
    return true;

  rep(i,
      cnt) { // ツ達ツ姪ァツづ個チツδコツつゥツづァツ新ツつオツつ「ツ偲シツ陛督づ個チツδコツづーツ選ツ妥ー
    rep(k, 4) {
      int tx = tatu_x[i] + dx[k];
      int ty = tatu_y[i] + dy[k];
      if (!inside(tx, ty) || field[ty][tx] == 0)
        continue;

      // ツ妥篠可楪つキツづゥツ和ツ姪ァツづ個チツδコ
      int ttx = kazu_x[i] + dx[(k + init_dir + (f ? 2 : 0)) % 4];
      int tty = kazu_y[i] + dy[(k + init_dir) % 4];
      if ((tx == ttx && ty == tty) || !inside(ttx, tty) || field[tty][ttx] == 0)
        continue;

      field[ty][tx] = 0;
      tatu_x[cnt] = tx, tatu_y[cnt] = ty;

      field[tty][ttx] = 0;
      kazu_x[cnt] = ttx, kazu_y[cnt] = tty;

      if (backtrack(cnt + 1, tS | (1LL << idx[make_pair(tx, ty)]),
                    kS | (1LL << idx[make_pair(ttx, tty)]), init_dir, f))
        return true;
      field[tty][ttx] = 1;
      field[ty][tx] = 1;
    }
  }
  visited[cnt][init_dir][f].insert(make_pair(tS, kS));
  return false;
}

bool solve() {
  int i, j, k;

  if (csize % 2)
    return false;

  // ツ達ツ姪ァ
  tatu_x[0] = cx[0], tatu_y[0] = cy[0];
  field[cy[0]][cx[0]] = 0;

  REP(j, 1, csize) { // ツ和ツ姪ァ
    kazu_x[0] = cx[j], kazu_y[0] = cy[j];
    field[cy[j]][cx[j]] = 0;

    rep(k, 4) {
      if (backtrack(1, 1LL, 1LL << j, k, 0))
        return true;
      if (backtrack(1, 1LL, 1LL << j, k, 1))
        return true;
    }
    field[cy[j]][cx[j]] = 1;
  }
  field[cy[0]][cx[0]] = 1;

  return false;
}

int main() {
  int i, j, k, u;

  while (cin >> w >> h, w | h) {
    // init
    idx.clear();
    rep(i, 20) rep(j, 4) rep(k, 2) visited[i][j][k].clear();
    csize = 0;

    // input
    rep(i, h) rep(j, w) {
      cin >> field[i][j];
      if (field[i][j] == 1) {
        cx[csize] = j, cy[csize] = i;
        idx[make_pair(j, i)] = csize;
        csize++;
      }
    }
    puts(solve() ? "YES" : "NO");
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <complex>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <map>
#include <set>
#include <vector>
using namespace std;

#define REP(i, a, n) for (i = a; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define foreach(it, x)                                                         \\
  for (typeof(x.begin()) it = x.begin(); it != x.end(); it++)

// YET_SYSTEM_TEST

typedef complex<int> P;
typedef long long ll;

const int dx[] = {0, 1, 0, -1};
const int dy[] = {-1, 0, 1, 0};
int w, h, tatu_x[20], tatu_y[20], kazu_x[20], kazu_y[20];
int field[12][12], cx[36], cy[36], csize;
map<pair<int, int>, int> idx;

struct state {
  ll tS, kS;
  int dir;
  bool f;
  state(ll _tS, ll _kS, int d, bool _f) { tS = _tS, kS = _kS, dir = d, f = _f; }
  bool operator<(const state &a) const {
    if (tS != a.tS)
      return tS < a.tS;
    if (kS != a.kS)
      return kS < a.kS;
    if (dir != a.dir)
      return dir < a.dir;
    return f < a.f;
  }
  bool operator==(const state &a) const {
    return (tS == a.tS && kS == a.kS && dir == a.dir && f == a.f);
  }
};

set<state> visited;

bool backtrack_tatu(int, ll, ll, int, bool);
bool backtrack_kazu(int, int, int, ll, ll, int, bool);

bool backtrack_kazu(int cnt, int id, int dir, ll tS, ll kS, int init_dir,
                    bool f) {
  int k;
  int tx = kazu_x[id] + dx[(dir + init_dir + (f ? 2 : 0)) % 4];
  int ty = kazu_y[id] + dy[(dir + init_dir) % 4];

  if (tx < 0 || tx >= w || ty >= h || ty < 0 || field[ty][tx] == 0)
    return false;

  field[ty][tx] = 0;
  kazu_x[cnt] = tx, kazu_y[cnt] = ty;
  if (backtrack_tatu(cnt + 1, tS, kS | (1LL << idx[make_pair(tx, ty)]),
                     init_dir, f))
    return true;
  field[ty][tx] = 1;

  return false;
}

bool backtrack_tatu(int cnt, ll tS, ll kS, int init_dir, bool f) {
  int i, j, k;
  ;

  if (visited.count(state(tS, kS, init_dir, f)))
    return false;
  if (csize / 2 == cnt)
    return true;

  // debug
  /*
  printf("n = %d, init_dir = %d\\n",n,init_dir);
  rep(i,n){
      cout << tatu[i] << " : " << kazu[i] << endl;
  }
  puts("");
  */

  rep(i,
      cnt) { // ツ達ツ姪ァツづ個チツδコツつゥツづァツ新ツつオツつ「ツ偲シツ陛督づ個チツδコツづーツ選ツ妥ー
    rep(k, 4) {
      int tx = tatu_x[i] + dx[k];
      int ty = tatu_y[i] + dy[k];
      if (tx < 0 || tx >= w || ty >= h || ty < 0 || field[ty][tx] == 0)
        continue;

      // printf("tx = %d, ty = %d\\n",tx,ty);
      field[ty][tx] = 0;
      tatu_x[cnt] = tx, tatu_y[cnt] = ty;
      if (backtrack_kazu(cnt, i, k, tS | (1LL << idx[make_pair(tx, ty)]), kS,
                         init_dir, f))
        return true;
      field[ty][tx] = 1;
    }
  }
  visited.insert(state(tS, kS, init_dir, f));
  return false;
}

bool solve() {
  int i, j, k;

  if (csize % 2)
    return false;

  rep(i, csize / 2) { // ツ達ツ姪ァ
    tatu_x[0] = cx[i], tatu_y[0] = cy[i];
    field[cy[i]][cx[i]] = 0;

    rep(j, csize) if (i != j) { // ツ和ツ姪ァ
      kazu_x[0] = cx[j], kazu_y[0] = cy[j];
      field[cy[j]][cx[j]] = 0;

      // if( backtrack_tatu(tatu, kazu, 1LL<<i, 1LL<<j, false) ) return true;
      rep(k, 4) {
        if (backtrack_tatu(1, 1LL << i, 1LL << j, k, false))
          return true;
        if (backtrack_tatu(1, 1LL << i, 1LL << j, k, true))
          return true;
      }
      // printf("tatu(%d,%d), kazu(%d,%d)\\n",cx[i],cy[i],cx[j],cy[j]);

      field[cy[j]][cx[j]] = 1;
    }

    field[cy[i]][cx[i]] = 1;
  }

  return false;
}

int main() {
  int i, j;

  while (cin >> w >> h, w | h) {
    // init
    idx.clear();
    visited.clear();
    csize = 0;

    // input
    rep(i, h) rep(j, w) {
      cin >> field[i][j];
      if (field[i][j] == 1) {
        cx[csize] = j, cy[csize] = i;
        idx[make_pair(j, i)] = csize;
        csize++;
      }
    }
    puts(solve() ? "YES" : "NO");
  }

  return 0;
}