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

#include <algorithm>
#include <cstdio>
#include <iostream>
#include <math.h>
#include <queue>
#include <string.h>
using namespace std;
typedef pair<int, int> P;
const int MAX_N = 1 << 24;
const int MAX_C = 8 * 7 * 6 * 5 * 4 * 3 * 2;
int checked[MAX_C + 10];
const int ele[] = {10000000, 1000000, 100000, 10000, 1000, 100, 10, 1};

int convert(int n) {
  bool used[8];
  memset(used, 0, sizeof(used));
  int ret = 0;
  for (int i = 0; i < 8; i++) {
    int x = n / ele[i]; // i番目の番号
    n %= ele[i];
    used[x] = true;
    int E = 1;
    for (int j = 1; j < 8 - i; j++)
      E *= j;
    int count = 0;
    for (int j = 0; j < x; j++)
      if (!used[j])
        count++;
    ret += count * E;
  }
  return ret;
}

int main(int argc, const char *argv[]) {
  fill(checked, checked + MAX_C + 10, MAX_C + 100);
  queue<P> que;
  // 数字と回数
  que.push(make_pair(1234567, 0));
  checked[convert(1234567)] = 0;
  // 上、右、下、左
  int dx[] = {0, 1, 0, -1};
  int dy[] = {-1, 0, 1, 0};
  while (!que.empty()) {
    P p = que.front();
    que.pop();
    int num = p.first;
    int count = p.second;
    int n[2][4]; // 現在の数値をカードの並びに変換
    int temp = num;
    // 0の位置
    int zx;
    int zy;
    for (int i = 0; i < 2; i++) {
      for (int j = 0; j < 4; j++) {
        n[i][j] = temp / ele[i * 4 + j];
        temp -= n[i][j] * ele[i * 4 + j];
        if (n[i][j] == 0) {
          zx = j;
          zy = i;
        }
      }
    }

    for (int i = 0; i < 4; i++) {
      // 交換する位置の候補
      int nx = zx + dx[i];
      int ny = zy + dy[i];
      // 交換可能
      if (nx >= 0 && nx < 4 && ny >= 0 && ny < 2) {
        int nxt = 0;
        for (int j = 0; j < 2; j++) {
          for (int k = 0; k < 4; k++) {
            if (j == ny && k == nx) {

            } else if (j == zy && k == zx) {
              nxt += n[ny][nx] * ele[j * 4 + k];
            } else {
              nxt += n[j][k] * ele[j * 4 + k];
            }
          }
        }
        int conv_nxt = convert(nxt);
        if (checked[conv_nxt] == MAX_C + 100) {
          checked[conv_nxt] = count + 1;
          que.push(make_pair(nxt, count + 1));
        }
      }
    }
  }

  int n[8];
  while (~scanf("%d%d%d%d%d%d%d%d", &n[0], &n[1], &n[2], &n[3], &n[4], &n[5],
                &n[6], &n[7])) {
    int num = 0;
    for (int i = 0; i < 8; i++) {
      num += n[i] * ele[i];
    }
    int conv_num = convert(num);
    printf("%d\\n", checked[conv_num]);
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cstdio>
#include <iostream>
#include <math.h>
#include <queue>
#include <string.h>
using namespace std;
typedef pair<int, int> P;
const int MAX_N = 1 << 24;
const int MAX_C = 8 * 7 * 6 * 5 * 4 * 3 * 2;
int checked[MAX_C + 10];
const int ele[] = {10000000, 1000000, 100000, 10000, 1000, 100, 10, 1};

int convert(int n) {
  bool used[8];
  memset(used, 0, sizeof(used));
  int ret = 0;
  for (int i = 0; i < 8; i++) {
    int x = n / ele[i]; // i番目の番号
    n %= ele[i];
    used[x] = true;
    int E = 1;
    for (int j = 1; j < 8 - i; j++)
      E *= j;
    int count = 0;
    for (int j = 0; j < x; j++)
      if (!used[j])
        count++;
    ret += count * E;
  }
  return ret;
}

int main(int argc, const char *argv[]) {
  fill(checked, checked + MAX_C + 10, MAX_C + 100);
  queue<P> que;
  // 数字と回数
  que.push(make_pair(1234567, 0));
  checked[convert(1234567)] = 0;
  // 上、右、下、左
  int dx[] = {0, 1, 0, -1};
  int dy[] = {-1, 0, 1, 0};
  while (!que.empty()) {
    P p = que.front();
    que.pop();
    int num = p.first;
    int count = p.second;
    int n[2][4]; // 現在の数値をカードの並びに変換
    int temp = num;
    // 0の位置
    int zx;
    int zy;
    for (int i = 0; i < 2; i++) {
      for (int j = 0; j < 4; j++) {
        n[i][j] = temp / ele[i * 4 + j];
        temp -= n[i][j] * ele[i * 4 + j];
        if (n[i][j] == 0) {
          zx = j;
          zy = i;
        }
      }
    }

    for (int i = 0; i < 4; i++) {
      // 交換する位置の候補
      int nx = zx + dx[i];
      int ny = zy + dy[i];
      // 交換可能
      if (nx >= 0 && nx < 4 && ny >= 0 && ny < 2) {
        int nxt = 0;
        for (int j = 0; j < 2; j++) {
          for (int k = 0; k < 4; k++) {
            if (j == ny && k == nx) {

            } else if (j == zy && k == zx) {
              nxt += n[ny][nx] * ele[j * 4 + k];
            } else {
              nxt += n[j][k] * ele[j * 4 + k];
            }
          }
        }
        int conv_nxt = convert(nxt);
        if (checked[conv_nxt] == MAX_C + 100) {
          checked[conv_nxt] = count + 1;
          que.push(make_pair(nxt, count + 1));
        }
      }
    }
  }
  while (true) {
    int n[8];
    while (~scanf("%d %d %d %d %d %d %d %d", &n[0], &n[1], &n[2], &n[3], &n[4],
                  &n[5], &n[6], &n[7])) {
      int num = 0;
      for (int i = 0; i < 8; i++) {
        num += n[i] * ele[i];
      }
      int conv_num = convert(num);
      printf("%d\\n", checked[conv_num]);
    }
  }
  return 0;
}