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

#include <algorithm>
#include <bitset>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <utility>
using namespace std;

#define ABS(a) (((a) >= 0) ? (a) : -(a))
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define MIN(a, b) ((a) > (b) ? (b) : (a))
#define FOR(i, a, b) for (int i = a; i < b; ++i)
#define RFOR(i, a, b) for (int i = a; i > b; --i)
#define REP(i, n) for (int i = 0; i < n; ++i)
#define int long long

typedef long long ll;
typedef pair<int, int> Pair;

const int kMaxH = 1000;
const int kMaxW = 1000;
const int kInf = 1000000000;

map<string, int> m;
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, -1, 0, 1};

class Field {
public:
  string f = "";
  int z;
  int cnt;

  bool MoveFrom(Field f0, int i) {
    f = f0.f;
    z = f0.z;
    cnt = f0.cnt;

    // 移動先の座標決定
    int nz;
    if (i == 0) { // 右
      if (z == 3 || z == 7) {
        return false;
      }
      nz = z + 1;
    } else if (i == 1) { // 下
      if (4 <= z && z <= 7) {
        return false;
      }
      nz = z + 4;
    } else if (i == 2) { // 左
      if (z == 0 || z == 4) {
        return false;
      }
      nz = z - 1;
    } else if (i == 3) { // 上
      if (0 <= z && z <= 3) {
        return false;
      }
      nz = z - 4;
    }

    // 入れ替えなど
    char tmp = f[z];
    f[z] = f[nz];
    f[nz] = tmp;
    z = nz;
    ++cnt;
    return true;
  }
};

void Init() {
  queue<Field> que;

  Field f0 = {"01234567", 0, 0};
  m[f0.f] = f0.cnt;
  que.push(f0);
  while (que.size()) {
    Field cf = que.front();
    que.pop();

    REP(i, 4) {
      Field nf;
      if (nf.MoveFrom(cf, i)) {
        if (m.find(nf.f) != m.end()) {
          continue;
        }
        que.push(nf);
        m[nf.f] = nf.cnt;
      }
    }
  }

  return;
}

signed main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  Init();
  while (true) {
    string s;
    REP(i, 8) {
      char c;
      cin >> c;
      if (cin.fail()) {
        goto r;
      }
      s.push_back(c);
    }
    int ans = m[s];
    cout << ans << endl;
  }
r:
  return 0;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <utility>
using namespace std;

#define ABS(a) (((a) >= 0) ? (a) : -(a))
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define MIN(a, b) ((a) > (b) ? (b) : (a))
#define FOR(i, a, b) for (int i = a; i < b; ++i)
#define RFOR(i, a, b) for (int i = a; i > b; --i)
#define REP(i, n) for (int i = 0; i < n; ++i)
#define int long long

typedef long long ll;
typedef pair<int, int> Pair;

const int kMaxH = 1000;
const int kMaxW = 1000;
const int kInf = 1000000000;

map<string, int> m;
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, -1, 0, 1};

class Field {
public:
  string f = "";
  int z;
  int cnt;

  bool MoveFrom(Field f0, int i) {
    f = f0.f;
    z = f0.z;
    cnt = f0.cnt;
    // cout << "---" << endl;
    // cout << f0.f << " " << i << endl;

    // 移動先の座標決定
    int nz;
    if (i == 0) { // 右
      if (z == 3 || z == 7) {
        return false;
      }
      nz = z + 1;
    } else if (i == 1) { // 下
      if (4 <= z && z <= 7) {
        return false;
      }
      nz = z + 4;
    } else if (i == 2) { // 左
      if (z == 0 || z == 4) {
        return false;
      }
      nz = z - 1;
    } else if (i == 3) { // 上
      if (0 <= z && z <= 3) {
        return false;
      }
      // cout << z << endl;
      nz = z - 4;
      // cout << nz << endl;
    }
    // cout << f0.f << " " << i << " " << z << " " << nz << endl;

    // 入れ替えなど
    char tmp = f[z];
    // cout << tmp << endl;
    f[z] = f[nz];
    // cout << f[z] << endl;
    f[nz] = tmp;
    // cout << f[nz] << endl;
    z = nz;
    // cout << z << endl;
    ++cnt;
    // cout << f << endl;
    return true;
  }
};

int Bfs(Field f0) {
  queue<Field> que;
  map<string, string> bt;
  que.push(f0);
  bt[f0.f] = "";
  // cout << bt["10234567"] << endl;

  while (que.size()) {
    // for (auto itr = bt.begin(); itr != bt.end(); ++itr) {
    //   cout << itr->first << " " << itr->second << "/";
    // }
    // cout << endl;
    // cout << que.front().f << endl;
    Field cf = que.front();
    que.pop();
    auto it = m.find(cf.f);
    if (it != m.end()) {
      // cout << cf.f << endl;
      // cout << bt[cf.f] << endl;
      // cout << bt[bt[cf.f]] << endl;
      string pf = bt[cf.f];
      int rest = it->second + 1;
      while (pf != "") {
        // cout << pf << endl;
        m[pf] = rest;
        pf = bt[pf];
        ++rest;
      }

      return cf.cnt + it->second;
    }

    REP(i, 4) {
      Field nf;
      if (nf.MoveFrom(cf, i)) {
        if (bt.find(nf.f) != bt.end()) {
          continue;
        }
        que.push(nf);
        bt[nf.f] = cf.f;
      }
    }
  }

  return -1;
}

signed main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  m["01234567"] = 0;
  while (true) {
    Field f0;
    REP(i, 8) {
      char c;
      cin >> c;
      if (cin.fail()) {
        break;
      }
      f0.f.push_back(c);
    }
    REP(i, 8) {
      if (f0.f[i] == '0') {
        f0.z = i;
      }
    }
    f0.cnt = 0;
    int ans = Bfs(f0);
    cout << ans << endl;
  }

  return 0;
}