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

#include <algorithm>
#include <iostream>
#include <map>
#include <queue>
#include <set>

#define rep(i, n) for (int i = 0; i < n; i++)
#define all(a) (a).begin(), (a).end()
#define fs first
#define sc second
using namespace std;

typedef pair<int, int> P;
typedef vector<P> H;

int n, k;
H snake(8);
set<P> block;
P goal;
int dy[] = {-1, -1, 0, 1, 1, 0}, dx[] = {0, 1, 1, 0, -1, -1};
vector<H> can;

void rec(H x, int depth, int prv) {
  if (depth == n) {
    can.push_back(x);
    return;
  }

  bool f1 = false, f2 = true;
  rep(d, 6) {
    P adj = x[depth];
    adj.fs += dx[d];
    adj.sc += dy[d];

    if (depth == 0 || adj == x[depth - 1])
      f1 = true;
    rep(i, depth - 1) {
      if (adj == x[i]) {
        f2 = false;
        break;
      }
    }
    if (!f2)
      break;
  }
  if (f1 && f2)
    rec(x, depth + 1, prv);

  if (prv + 1 != depth) {
    rep(d, 6) {
      P nxt = x[depth];
      nxt.fs += dx[d];
      nxt.sc += dy[d];
      if (block.find(nxt) != block.end())
        continue;

      bool f = true;
      rep(i, depth) {
        if (x[i] == nxt) {
          f = false;
          break;
        }
      }
      if (!f)
        continue;

      f1 = false, f2 = true;
      rep(d2, 6) {
        P adj = nxt;
        adj.fs += dx[d2];
        adj.sc += dy[d2];

        if (depth == 0 || adj == x[depth - 1])
          f1 = true;
        rep(i, depth - 1) {
          if (adj == x[i]) {
            f2 = false;
            break;
          }
        }
        if (!f2)
          break;
      }
      if (f1 && f2) {
        swap(nxt, x[depth]);
        rec(x, depth + 1, depth);
        swap(nxt, x[depth]);
      }
    }
  }
}

int main() {
  while (cin >> n, n) {
    rep(i, n) cin >> snake[i].fs >> snake[i].sc;
    cin >> k;
    block.clear();
    rep(i, k) {
      cin >> goal.fs >> goal.sc;
      block.insert(goal);
    }
    cin >> goal.fs >> goal.sc;

    map<H, int> m;
    m[snake] = 0;
    queue<H> q;
    q.push(snake);

    while (q.size()) {
      snake = q.front();
      q.pop();
      int nxt = m[snake] + 1;

      can.clear();
      rec(snake, 0, -2);
      rep(i, can.size()) {
        if (m.find(can[i]) == m.end()) {
          if (can[i][0] == goal) {
            cout << nxt << endl;
            goto END;
          }
          m[can[i]] = nxt;
          q.push(can[i]);
        }
      }
    }
  END:;
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <iostream>
#include <map>
#include <queue>
#include <set>

#define rep(i, n) for (int i = 0; i < n; i++)
#define all(a) (a).begin(), (a).end()
#define fs first
#define sc second
using namespace std;

typedef pair<int, int> P;
typedef vector<P> H;

int n, k;
H snake(8);
set<P> block;
P goal;
int dy[] = {-1, -1, 0, 1, 1, 0}, dx[] = {0, 1, 1, 0, -1, -1};
vector<H> can;

void rec(H x, int depth, int prv) {
  if (depth == n) {
    can.push_back(x);
    return;
  }

  rec(x, depth + 1, prv);

  if (prv + 1 != depth) {
    rep(d, 6) {
      P nxt = x[depth];
      nxt.fs += dx[d];
      nxt.sc += dy[d];
      if (block.find(nxt) != block.end())
        continue;

      set<int> ids;
      rep(i, 6) {
        P adj = nxt;
        adj.fs += dx[i];
        adj.sc += dy[i];
        rep(j, n) {
          if (j == depth)
            continue;
          if (adj == x[j])
            ids.insert(j);
        }
      }
      if (0 < depth && depth < n - 1) {
        if (ids.size() != 2)
          continue;
      } else {
        if (ids.size() != 1)
          continue;
      }
      if (depth != 0 && ids.find(depth - 1) == ids.end())
        continue;
      if (depth != n - 1 && ids.find(depth + 1) == ids.end())
        continue;

      swap(nxt, x[depth]);
      rec(x, depth + 1, depth);
      swap(nxt, x[depth]);
    }
  }
}

int main() {
  while (cin >> n, n) {
    rep(i, n) cin >> snake[i].fs >> snake[i].sc;
    cin >> k;
    block.clear();
    rep(i, k) {
      cin >> goal.fs >> goal.sc;
      block.insert(goal);
    }
    cin >> goal.fs >> goal.sc;

    map<H, int> m;
    m[snake] = 0;
    queue<H> q;
    q.push(snake);

    while (q.size()) {
      snake = q.front();
      q.pop();
      int nxt = m[snake] + 1;

      can.clear();
      rec(snake, 0, -2);
      rep(i, can.size()) {
        if (m.find(can[i]) == m.end()) {
          if (can[i][0] == goal) {
            // rep(j,n)cout << can[i][j].fs << " " << can[i][j].sc << endl;
            cout << nxt << endl;
            goto END;
          }
          m[can[i]] = nxt;
          q.push(can[i]);
        }
      }
    }
  END:;
  }
}