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

#include <algorithm>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

using namespace std;

typedef long long ll;
typedef ll li;
typedef pair<int, int> PI;
#define EPS (1e-10L)
#define rep(i, n) for (int i = 0; i < (int)(n); ++i)
#define F first
#define S second
#define mp(a, b) make_pair(a, b)
#define pb(a) push_back(a)
#define SZ(a) (int)((a).size())
#define ALL(a) a.begin(), a.end()
#define FOR(it, a) for (__typeof(a.begin()) it = a.begin(); it != a.end(); ++it)
void pkuassert(bool t) { t = 1 / t; };
/*
int dx[]={0,1,0,-1,1,1,-1,-1};
int dy[]={1,0,-1,0,-1,1,1,-1};
*/

int dx[] = {0, 1, 1, 0, -1, -1};
int dy[] = {-1, -1, 0, 1, 1, 0};
int n;

priority_queue<pair<PI, vector<PI>>> q;
vector<PI> cv;
set<PI> rock;
set<vector<PI>> app;
PI cc;

int dist(PI a, PI b) {
  int cx = a.F - b.F;
  int cy = a.S - b.S;
  if (cx == 0 && cy == 0)
    return 0;
  rep(i, 6) if (cx == dx[i] && cy == dy[i]) return 1;

  return 2;
}

map<PI, int> shortest;
int X, Y;
void next(int idx) {

  if (idx == n) {
    if (app.count(cv))
      return;
    rep(i, n) {
      if (i && dist(cv[i - 1], cv[i]) != 1)
        return;
      if (i + 1 < n && dist(cv[i], cv[i + 1]) != 1)
        return;
      for (int j = 0; j <= i - 2; ++j)
        if (dist(cv[i], cv[j]) <= 1)
          return;
    }
    int ddx = X - cv[0].F;
    int ddy = Y - cv[0].S;
    if (!shortest.count(mp(ddx, ddy)))
      return;
    if ((shortest[mp(ddx, ddy)] - cc.S + 1) > 20)
      return;
    q.push(mp(mp(-(shortest[mp(ddx, ddy)] - cc.S + 1), cc.S - 1), cv));
    return;
  }

  next(idx + 1);

  rep(i, 6) {
    cv[idx].F += dx[i];
    cv[idx].S += dy[i];
    if (!rock.count(cv[idx]) && (idx == 0 || dist(cv[idx], cv[idx - 1]) == 1))
      next(min(idx + 2, n));
    cv[idx].F -= dx[i];
    cv[idx].S -= dy[i];
  }
}

void solve() {
  cv.clear();
  cv.resize(n);
  rep(i, n) cin >> cv[i].F >> cv[i].S;
  int k;
  cin >> k;
  rock.clear();
  rep(i, k) {
    int x, y;
    cin >> x >> y;
    rock.insert(mp(x, y));
  }
  cin >> X >> Y;
  q = priority_queue<pair<PI, vector<PI>>>();
  q.push(mp(mp(0, 0), cv));
  app.clear();
  int oc = 0;
  while (!q.empty()) {
    cc = q.top().F;
    cv = q.top().S;
    q.pop();
    int dix = cv[0].F - X;
    int diy = cv[0].S - Y;
    if (-cc.F > 20)
      continue;
    if (-cc.S > 20)
      return;
    if (app.count(cv))
      continue;
    if (cv[0].F == X && cv[0].S == Y) {
      cout << -cc.S << endl;
      return;
    }
    if (cc.S != oc) {
      oc = cc.S;
      // cout << cc << endl;
    }
    app.insert(cv);
    next(0);
  }
  cout << -1 << endl;
}

int main(int argc, char *argv[]) {
  queue<pair<PI, int>> q;
  q.push(mp(mp(0, 0), 0));
  while (!q.empty()) {
    PI cv = q.front().F;
    int cc = q.front().S;
    q.pop();
    if (shortest.count(cv))
      continue;
    if (cc > 20)
      continue;
    shortest[cv] = cc;
    rep(i, 6) q.push(mp(mp(cv.F + dx[i], cv.S + dy[i]), cc + 1));
  }

  while (cin >> n && n)
    solve();
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

using namespace std;

typedef long long ll;
typedef ll li;
typedef pair<int, int> PI;
#define EPS (1e-10L)
#define rep(i, n) for (int i = 0; i < (int)(n); ++i)
#define F first
#define S second
#define mp(a, b) make_pair(a, b)
#define pb(a) push_back(a)
#define SZ(a) (int)((a).size())
#define ALL(a) a.begin(), a.end()
#define FOR(it, a) for (__typeof(a.begin()) it = a.begin(); it != a.end(); ++it)
void pkuassert(bool t) { t = 1 / t; };
/*
int dx[]={0,1,0,-1,1,1,-1,-1};
int dy[]={1,0,-1,0,-1,1,1,-1};
*/

int dx[] = {0, 1, 1, 0, -1, -1};
int dy[] = {-1, -1, 0, 1, 1, 0};
int n;

queue<pair<int, vector<PI>>> q;
vector<PI> cv;
set<PI> rock;
set<vector<PI>> app;
int cc;

int dist(PI a, PI b) {
  int cx = a.F - b.F;
  int cy = a.S - b.S;
  if (cx == 0 && cy == 0)
    return 0;
  rep(i, 6) if (cx == dx[i] && cy == dy[i]) return 1;

  return 2;
}

void next(int idx) {
  if (idx == n) {
    if (app.count(cv))
      return;
    rep(i, n) {
      if (i && dist(cv[i - 1], cv[i]) != 1)
        return;
      if (i + 1 < n && dist(cv[i], cv[i + 1]) != 1)
        return;
      for (int j = 0; j <= i - 2; ++j)
        if (dist(cv[i], cv[j]) <= 1)
          return;
    }
    q.push(mp(cc + 1, cv));
    return;
  }

  next(idx + 1);

  rep(i, 6) {
    cv[idx].F += dx[i];
    cv[idx].S += dy[i];
    if (!rock.count(cv[idx]))
      next(min(idx + 2, n));
    cv[idx].F -= dx[i];
    cv[idx].S -= dy[i];
  }
}

map<PI, int> shortest;

void solve() {
  cv.clear();
  cv.resize(n);
  rep(i, n) cin >> cv[i].F >> cv[i].S;
  int k;
  cin >> k;
  rock.clear();
  rep(i, k) {
    int x, y;
    cin >> x >> y;
    rock.insert(mp(x, y));
  }
  int X, Y;
  cin >> X >> Y;
  q = queue<pair<int, vector<PI>>>();
  q.push(mp(0, cv));
  app.clear();
  int oc = 0;
  while (!q.empty()) {
    cc = q.front().F;
    cv = q.front().S;
    q.pop();
    int dix = cv[0].F - X;
    int diy = cv[0].S - Y;
    if (!shortest.count(mp(dix, diy)) || shortest[mp(dix, diy)] + cc > 20)
      continue;
    if (cc > 20)
      return;
    if (app.count(cv))
      continue;
    if (cv[0].F == X && cv[0].S == Y) {
      cout << cc << endl;
      return;
    }
    if (cc != oc) {
      oc = cc;
      // cout << cc << endl;
    }
    app.insert(cv);
    next(0);
  }
  cout << -1 << endl;
}

int main(int argc, char *argv[]) {
  queue<pair<PI, int>> q;
  q.push(mp(mp(0, 0), 0));
  while (!q.empty()) {
    PI cv = q.front().F;
    int cc = q.front().S;
    q.pop();
    if (shortest.count(cv))
      continue;
    if (cc > 20)
      continue;
    shortest[cv] = cc;
    rep(i, 6) q.push(mp(mp(cv.F + dx[i], cv.S + dy[i]), cc + 1));
  }

  while (cin >> n && n)
    solve();
  return 0;
}