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

#include <algorithm>
#include <cassert>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
#define REP(i, s, n) for (int i = s; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define INF 1 << 27
#define all(n) n.begin(), n.end()
#define insert(a, b, c, d) PP(P(a, b), P(c, d))
#define F first
#define S second
#define pb push_back
#define foreach(i, c) for (iter(c) i = (c).begin(); i != (c).end(); ++i)
using namespace std;
typedef pair<int, int> P;
typedef pair<P, P> PP;
typedef pair<string, int> SI;
typedef long long ll;
typedef unsigned long long ull;
const int d[4] = {-2, -8, +2, +8};

string::size_type zero_finder(string s) {
  string::size_type index = s.find("0");
  return index == string::npos ? -1 : index;
}

inline bool range_check(string s, int dir, int pos) {
  int new_pos = pos + d[dir];
  assert(new_pos % 2 == 0);
  assert(pos % 2 == 0);
  if (!(0 <= new_pos && new_pos <= 14))
    return false;
  bool pis_top, npis_top;
  if (0 <= pos && pos <= 6)
    pis_top = true;
  else if (8 <= pos && pos <= 14)
    pis_top = false;
  else
    assert(false);

  if (0 <= new_pos && new_pos <= 6)
    npis_top = true;
  else if (8 <= new_pos && new_pos <= 14)
    npis_top = false;
  else
    assert(false);

  if (pis_top != npis_top && (dir == 0 || dir == 2))
    return false;
  return true;
}

inline void s_swap(string &s, int a, int b) {
  char store = s[a];
  s[a] = s[b];
  s[b] = store;
}

int main() {
  string input;
  map<string, int> ans;

  ans["0 1 2 3 4 5 6 7"] = 0;

  queue<SI> que;

  que.push(SI("0 1 2 3 4 5 6 7", 0));

  bool first_time = true;

  while (!que.empty()) {
    SI si = que.front();
    que.pop();
    if (ans[si.F] != 0 && !first_time)
      continue;

    ans[si.F] = si.S;
    first_time = false;
    rep(i, 4) {

      int pos = zero_finder(si.F);
      int n_pos = pos + d[i];

      assert(pos != -1);

      if (!range_check(si.F, i, pos))
        continue;

      string next_s = si.F;
      s_swap(next_s, pos, n_pos);
      que.push(SI(next_s, si.S + 1));
    }
  }

  while (getline(cin, input)) {
    cout << ans[input] << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <deque>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <sstream>
#include <stack>
#include <vector>
#define all(n) n.begin(), n.end()
#define REP(i, s, n) for (int i = s; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define insert(a, b, c) PP(SI(a, b), c)
#define F first
#define S second
#define pb push_back
#define pf push_front
#define INF (1 << 27)
#define EPS 1e-10
#define equals(a, b) (fabs((a) - (b)) < EPS)

using namespace std;
typedef pair<int, int> P;
typedef pair<string, int> SI;
typedef pair<SI, int> PP;
typedef unsigned long long ull;
typedef long long ll;
const int dx[4] = {0, 1, 0, -1};
const int dy[4] = {1, 0, -1, 0};
const string solve = "0 1 2 3 4 5 6 7";
const int mv[4] = {+2, -2, +8, -8};

int stoi(string s) {
  stringstream ss;
  int d[8];
  ss << s;
  ss >> d[0] >> d[1] >> d[2] >> d[3] >> d[4] >> d[5] >> d[6] >> d[7];
  int sum = 0;
  rep(i, 8) {
    sum *= 10;
    sum += d[i];
  }
  return sum;
}

int main() {
  string s;
  int a, b, c, d, e, f, g, h;
  while (cin >> a >> b >> c >> d >> e >> f >> g >> h) {
    // cout << "s - " << s << endl;
    stringstream ss;
    ss << a << b << c << d << e << f << g << h;
    // cout << ss.str() << endl;
    string s2;
    ss >> s2;
    s.clear();
    rep(i, s2.length()) {
      s += s2[i];
      if (i != s2.length() - 1)
        s += ' ';
    }
    // cout << s << endl;

    int zero = -1;
    rep(i, s.length()) if (s[i] == '0') {
      zero = i;
      break;
    }
    assert(zero != -1);
    map<string, bool> used_pattern;
    deque<PP> deq;
    deq.pf(insert(s, 0, zero)); // string / counter / 0-pos
    used_pattern[s] = true;
    // bool bmap[76543210];

    int cnt = INT_MAX;

    while (!deq.empty()) {
      PP pp = deq.front();
      deq.pop_front();
      // cout << "pp.F,F = " << pp.F.F << endl;
      // cout << "pp = "<< pp.F.F << "," << pp.F.S << "," << pp.S  << endl;
      if (pp.F.S >= cnt)
        continue;
      if (pp.F.F == solve) {
        // cout << "pp = "<< pp.F.F << "," << pp.F.S << "," << pp.S  << endl;
        cnt = min(cnt, pp.F.S);
        // continue;
        break;
      }

      rep(i, 4) {
        int next = pp.S + mv[i];
        if (!(0 <= next && next <= 14))
          continue;
        if (0 <= pp.S && pp.S <= 6) {
          if ((i == 0 || i == 1) && !(0 <= next && next <= 6))
            continue;
        } else if (8 <= pp.S && pp.S <= 14) {
          if ((i == 0 || i == 1) && !(8 <= next && next <= 14))
            continue;
        }
        string bkup = pp.F.F;

        // cout <<"o? " << pp.F.F[pp.S] << ", F["<<next<<"] = " << pp.F.F[next]
        // << ", pre pp.F.F = " << pp.F.F<< endl;
        assert(pp.F.F[pp.S] == '0');
        char pre = pp.F.F[next];
        pp.F.F[next] = pp.F.F[pp.S];
        pp.F.F[pp.S] = pre;
        if (used_pattern[pp.F.F]) {
          // if(
          // bmap[pp.F.F[0]-'0'][pp.F.F[2]-'0'][pp.F.F[4]-'0'][pp.F.F[6]-'0'][pp.F.F[8]-'0'][pp.F.F[10]-'0'][pp.F.F[12]-'0'][pp.F.F[14]-'0']
          // ){
          pp.F.F = bkup;
          continue;
        }
        used_pattern[pp.F.F] = true;
        // cout << "change pp.F.F = " << pp.F.F <<",next = " << next<< endl;
        if (pp.F.S + 1 >= deq.front().F.S)
          deq.pb(insert(pp.F.F, pp.F.S + 1, next));
        else
          deq.pf(insert(pp.F.F, pp.F.S + 1, next));
        pp.F.F = bkup;
      }
    }
    assert(cnt != INT_MAX);
    cout << cnt << endl;
  }
  return 0;
}

/*
Way to check the time of processing speed

clock_t start,end;
start = clock();

------function-------

end = clock();
cout << setiosflags(ios::fixed) << setprecision(10) <<
(double)(end-start)/CLOCKS_PER_SEC << endl;


*/