Problem p00724 (C++) — buggy submission, verdict: Runtime Error

#include <algorithm>
#include <climits>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <map>
#include <queue>
#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++)

const int dx[] = {0, 1, 1, 0, -1, -1};
const int dy[] = {-1, -1, 0, 1, 1, 0};
int N, K, goalX, goalY;
int res;
vector<pair<int, int>> snake_init;
map<vector<pair<int, int>>, int> dp;
set<vector<pair<int, int>>> used;
set<pair<int, int>> stone;

// {{{ input() //
void input() {
  int i, j, k;

  rep(i, N) {
    int x, y;
    cin >> x >> y;
    snake_init.push_back(make_pair(x, y));
  }
  // stone
  cin >> K;
  rep(i, K) {
    int u, v;
    cin >> u >> v;
    stone.insert(make_pair(u, v));
  }
  cin >> goalX >> goalY;
}
// }}} //

bool ccc(int idx, const vector<pair<int, int>> &buf) {
  int i, j, k;
  int res = 0;

  if (stone.count(buf[idx]))
    return false;
  if (idx == 0 || idx == buf.size() - 1)
    res = 1;

  rep(i, idx) if (buf[i] == buf[idx]) return false;

  rep(k, 6) {
    int tx = buf[idx].first + dx[k];
    int ty = buf[idx].second + dy[k];
    if (idx != 0) {
      if (buf[idx - 1].first == tx && buf[idx - 1].second == ty)
        res++;
    }
    if (idx != N - 1) {
      if (buf[idx + 1].first == tx && buf[idx + 1].second == ty)
        res++;
    }
    rep(i, idx - 1) {
      if (buf[i].first == tx && buf[i].second == ty)
        return false;
    }
  }
  return res == 2;
}

// {{{ dfs //

void dfs(int idx, bool f, int cost, queue<vector<pair<int, int>>> &q,
         vector<pair<int, int>> &buf) {
  int i, j, k;

  if (idx > 0 &&
      (20 < cost + max(abs(buf[0].first - goalX), abs(buf[0].second - goalY))))
    return;

  if (idx == N) {
    if (dp.count(buf) == 0) {
      dp[buf] = cost + 1;
      q.push(buf);
      if (buf[0].first == goalX && buf[0].second == goalY) {
        res = cost + 1;
      }
    }
    return;
  }

  if (ccc(idx, buf))
    dfs(idx + 1, true, cost, q, buf);

  if (idx == 0 || f) {
    rep(k, 6) {
      buf[idx].first += dx[k];
      buf[idx].second += dy[k];
      if (ccc(idx, buf))
        dfs(idx + 1, false, cost, q, buf);
      buf[idx].first -= dx[k];
      buf[idx].second -= dy[k];
      if (res != INT_MAX)
        return;
    }
  }
}

// }}} //

void bfs() {
  int i, j, u, v, k;

  queue<vector<pair<int, int>>> q;
  q.push(snake_init);
  dp[snake_init] = 0;

  while (!q.empty()) {
    vector<pair<int, int>> &tmpv = q.front();
    int cost = dp[tmpv];

    if (cost > 20 || res != INT_MAX)
      break;

    if (used.count(tmpv))
      continue;
    used.insert(tmpv);

    dfs(0, true, cost, q, tmpv);
    q.pop();
  }
}

int main() {

  while (cin >> N, N) {
    // init
    res = INT_MAX;
    snake_init.clear();
    stone.clear();
    used.clear();
    dp.clear();

    input();

    bfs();
    cout << res << endl;
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <climits>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <map>
#include <queue>
#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++)

const int dx[] = {0, 1, 1, 0, -1, -1};
const int dy[] = {-1, -1, 0, 1, 1, 0};
int N, K, X, Y;
int S[10], res;
vector<pair<int, int>> snake_init;
map<vector<pair<int, int>>, int> dp;
set<vector<pair<int, int>>> used;
set<pair<int, int>> stone;

map<vector<pair<int, int>>, vector<vector<pair<int, int>>>> mmm;

void input() {
  int i, j, k;

  rep(i, N) {
    int x, y;
    cin >> x >> y;
    snake_init.push_back(make_pair(x, y));
  }

  // eßÅ×ÚóÔðßé
  rep(i, N) {
    int ss = 0;
    rep(j, N) if (i != j) {
      rep(k, 6) {
        int tx = snake_init[j].first + dx[k];
        int ty = snake_init[j].second + dy[k];
        if (tx == snake_init[i].first && ty == snake_init[i].second) {
          ss |= 1 << j;
          break;
        }
      }
    }
    S[i] = ss;
  }

  // stone
  cin >> K;
  rep(i, K) {
    int u, v;
    cin >> u >> v;
    stone.insert(make_pair(u, v));
  }
  cin >> X >> Y;
}

void BFS() {
  int i, j, u, v, k;

  // mask[0]ªæªÜÞ
  int mask[2] = {0};
  rep(i, N) mask[i % 2] |= 1 << i;

  queue<vector<pair<int, int>>> q;
  q.push(snake_init);
  dp[snake_init] = 0;

  return;
  while (!q.empty()) {
    vector<pair<int, int>> &tmpv = q.front();
    int cost = dp[tmpv];

    if (cost >= 20 || res != INT_MAX)
      break;

    if (used.count(tmpv))
      continue;
    used.insert(tmpv);

    // ³K»
    int xd = tmpv[0].first, yd = tmpv[0].second;
    vector<pair<int, int>> cur;
    rep(i, N) cur.push_back(make_pair(tmpv[i].first - xd, tmpv[i].second - yd));

    vector<pair<int, int>> next;
    vector<vector<pair<int, int>>> hoge = mmm[cur];

    rep(i, hoge.size()) {
      next.clear();
      rep(j, N) {
        next.push_back(
            make_pair(hoge[i][j].first + xd, hoge[i][j].second + yd));
      }

      // stone
      rep(j, N) if (stone.count(next[j])) break;
      if (j < next.size())
        continue;

      if (dp.count(next) == 0) {
        dp[next] = cost + 1;
        q.push(next);
        if (next[0].first == X && next[0].second == Y) {
          res = min(res, cost + 1);
          break;
        }
      }
    }
    q.pop();
  }
}

/*<*******************************************************************/
// Vµ¢ß(x,y), ¼ÌßÆ
bool isonecheck(int x, int y, const vector<pair<int, int>> &v) {
  int i, k;

  // d¡
  rep(i, v.size()) if (v[i].first == x && v[i].second == y) return false;

  rep(i, v.size() - 1) {
    rep(k, 6) {
      int tx = v[i].first + dx[k];
      int ty = v[i].second + dy[k];
      if (tx == x && ty == y)
        return false;
    }
  }
  return true;
}

// ISOKÌOÉsetuðµÄ¨­Kvª é
int SSS[10];
void setu(const vector<pair<int, int>> &init) {
  int i, j, k, n = init.size();

  rep(i, n) {
    int ss = 0;
    rep(j, n) if (i != j) {
      rep(k, 6) {
        int tx = init[i].first + dx[k];
        int ty = init[i].second + dy[k];
        if (init[j].first == tx && init[j].second == ty) {
          ss |= 1 << j;
          break;
        }
      }
    }
    SSS[i] = ss;
  }
}

bool ISOK(const vector<pair<int, int>> &buf) {
  int i, j, k, n = buf.size();

  // Ü¸Íd¡`FbN
  rep(i, n) {
    rep(j, n) if (i != j) {
      if (buf[i].first == buf[j].first && buf[i].second == buf[j].second)
        return false;
    }
  }

  // ³ÌÚ±óÔÆêvµÄé©
  rep(i, n) {
    int ss = 0;
    rep(j, n) if (i != j) {
      rep(k, 6) {
        int tx = buf[j].first + dx[k];
        int ty = buf[j].second + dy[k];
        if (buf[i].first == tx && buf[i].second == ty) {
          ss |= 1 << j;
          break;
        }
      }
    }
    if (SSS[i] != ss)
      return false;
  }
  return true;
}

// test
int rx[10], ry[10];
void ddd(int ni, int sub, vector<pair<int, int>> &init) {
  int i, j, k, n = init.size();

  if (sub == 0) {
    vector<pair<int, int>> buf;
    rep(i, n) buf.push_back(make_pair(rx[i], ry[i]));

    if (ISOK(buf)) {
      mmm[init].push_back(buf);
    }
    return;
  }

  REP(i, ni, n) if (sub & (1 << i)) {
    int tmpx = rx[i], tmpy = ry[i];

    rep(k, 6) {
      int tx = rx[i] + dx[k];
      int ty = ry[i] + dy[k];

      rx[i] = tx, ry[i] = ty;
      ddd(i + 1, sub & ~(1 << i), init);
      rx[i] = tmpx, ry[i] = tmpy;
    }
  }
}

// test
/*
  ÅãÌßÉÎµÄVµ¢6ß·
  d¡Í¶ÝµÈ¢Í¸
 */
void gen() {
  int i, j, k, n;

  puts("gen yet...");
  vector<vector<pair<int, int>>> vvp;

  vector<pair<int, int>> init;
  init.push_back(make_pair(0, 0));

  queue<vector<pair<int, int>>> q;
  q.push(init);

  vector<pair<int, int>> tmp;
  while (!q.empty()) {
    vector<pair<int, int>> &v = q.front();

    if (v.size() == 8)
      break;

    rep(k, 6) {
      int tx = v[v.size() - 1].first + dx[k];
      int ty = v[v.size() - 1].second + dy[k];
      if (isonecheck(tx, ty, v)) {
        tmp = v;
        tmp.push_back(make_pair(tx, ty));
        vvp.push_back(tmp);
        q.push(tmp);
      }
    }
    q.pop();
  }

  // ±±©çeóÔÉÎµÄ®«ûÌp^[ð²×é

  int mask[2];

  rep(i, vvp.size()) {

    mask[0] = mask[1] = 0;
    rep(j, vvp[i].size()) if (j % 2 == 0) mask[0] |= 1 << j;
    else mask[1] |= 1 << j;

    // ßÌÚ±ÖWðßÄ¨­
    setu(vvp[i]);

    // rx, ryðZbg·é
    rep(j, vvp[i].size()) rx[j] = vvp[i][j].first, ry[j] = vvp[i][j].second;

    rep(j, 2) {
      for (int sub = mask[j]; sub > 0; sub = (sub - 1) & mask[j]) {
        // printf("j = %d,  sub = %d\\n",j,sub);
        ddd(0, sub, vvp[i]);
      }
    }
  }
  puts("gen end.");
}
/**********************************************************************>*/

int main() {

  gen();
  // return 0;

  while (cin >> N, N) {
    // init
    res = INT_MAX;
    snake_init.clear();
    stone.clear();
    used.clear();
    dp.clear();

    input();

    BFS();
    cout << res << endl;
  }

  return 0;
}