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

#include <cstdio>
#include <cstring>
#include <limits.h>
#include <queue>
using namespace std;

class board {
public:
  int a;
  int z;
  int pz;
  board() : a(0), z(0), pz(0) {}
  board(int _a, int _z, int _pz) : a(_a), z(_z), pz(_pz) {}
};

int fact[7] = {1, 2, 6, 24, 120, 720, 5040};

int p2a(int *p) {
  int r = 0;
  int tmp[8];
  for (int i = 0; i < 8; i++)
    tmp[i] = i;
  for (int i = 0; i < 7; i++) {
    r += tmp[p[i]] * fact[6 - i];
    for (int j = p[i] + 1; j < 8; j++)
      --tmp[j];
  }
  return r;
}

void a2p(int a, int *p) {
  int t = a;
  int x;
  int tmp[8];
  for (int i = 0; i < 8; i++)
    tmp[i] = i;
  for (int i = 0; i < 7; i++) {
    x = t / fact[6 - i];
    p[i] = tmp[x];
    for (int j = x; j < 7 - i; j++)
      tmp[j] = tmp[j + 1];
    t %= fact[6 - i];
  }
  p[7] = tmp[0];
}

int main() {
  int p[8];
  int d[8][3] = {{1, 4, 0},  {-1, 1, 4},  {-1, 1, 4},  {-1, 4, 0},
                 {-4, 1, 0}, {-4, -1, 1}, {-4, -1, 1}, {-4, -1, 0}};
  queue<board> q;
  board b;
  int dist[40320];
  bool flg;
  int tmp, z;

  for (int i = 0; i < 40320; i++) {
    dist[i] = INT_MAX;
  }
  for (int i = 0; i < 8; i++) {
    p[i] = i;
  }
  tmp = p2a(p);
  dist[tmp] = 0;
  q.push(board(tmp, 0, 0));
  while (!q.empty()) {
    b = q.front();
    q.pop();
    a2p(b.a, p);
    for (int i = 0; i < 3; i++) {
      if (d[b.z][i]) {
        z = b.z + d[b.z][i];
        if (z == b.pz)
          continue;
        if (z >= 0 && z < 8) {
          a2p(b.a, p);
          tmp = p[b.z];
          p[b.z] = p[z];
          p[z] = tmp;
          tmp = p2a(p);
          if (dist[tmp] == INT_MAX) {
            dist[tmp] = dist[b.a] + 1;
            q.push(board(tmp, z, b.z));
          }
        }
      }
    }
  }
  while (scanf("%d %d %d %d %d %d %d %d", &p[0], &p[1], &p[2], &p[3], &p[4],
               &p[5], &p[6], &p[7]) == 8) {
    tmp = p2a(p);
    printf("%d\\n", dist[tmp]);
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <cstdio>
#include <cstring>
#include <queue>
#include <set>
using namespace std;

class board {
public:
  int a;
  int z;
  int pz;
  int s;
  board() : a(0), z(0), pz(0), s(0) {}
  board(int _a, int _z, int _pz, int _s) : a(_a), z(_z), pz(_pz), s(_s) {}
};

int p2a(int *p) {
  int r = 0;
  for (int i = 7; i >= 0; i--) {
    r <<= 4;
    r += p[i];
  }
  return r;
}

void a2p(int a, int *p) {
  int t = a;
  for (int i = 0; i < 8; i++) {
    p[i] = t & 0xF;
    t >>= 4;
  }
}

int main() {
  int p[8];
  int d[8][3] = {{1, 4, 0},  {-1, 1, 4},  {-1, 1, 4},  {-1, 4, 0},
                 {-4, 1, 0}, {-4, -1, 1}, {-4, -1, 1}, {-4, -1, 0}};
  board b;
  bool flg;
  int tmp, z;

  while (scanf("%d %d %d %d %d %d %d %d", &p[0], &p[1], &p[2], &p[3], &p[4],
               &p[5], &p[6], &p[7]) == 8) {
    queue<board> q;
    set<int> memory;
    for (int i = 0; i < 8; i++) {
      if (!p[i]) {
        z = i;
        break;
      }
    }
    tmp = p2a(p);
    q.push(board(tmp, z, z, 0));
    memory.insert(tmp);
    while (!q.empty()) {
      b = q.front();
      q.pop();
      a2p(b.a, p);
      flg = true;
      for (int i = 0; i < 8; i++) {
        if (p[i] != i) {
          flg = false;
          break;
        }
      }
      if (flg)
        break;

      for (int i = 0; i < 3; i++) {
        if (d[b.z][i]) {
          z = b.z + d[b.z][i];
          if (z == b.pz)
            continue;
          if (z >= 0 && z < 8) {
            a2p(b.a, p);
            tmp = p[b.z];
            p[b.z] = p[z];
            p[z] = tmp;
            tmp = p2a(p);
            if (memory.find(tmp) == memory.end()) {
              memory.insert(tmp);
              q.push(board(tmp, z, b.z, b.s + 1));
            }
          }
        }
      }
    }
    printf("%d\\n", b.s);
  }

  return 0;
}