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

#include <algorithm>
#include <cstdio>
#include <queue>
#include <utility>

#define N 40330

using namespace std;

typedef long long LL;

queue<int> que;
int *ckr;
int NN;

int ip[8];
int sample[8] = {0, 1, 2, 3, 4, 5, 6, 7};
int **smps;

int SN(int si, int ei, LL p) {
  LL pr = 0;
  int md = (si + ei) / 2;
  for (LL i = 0; i < 8; i++) {
    pr = pr * 8 + smps[md][i];
  }
  if (pr == p)
    return md;
  if (pr < p)
    return SN(md, ei, p);
  if (pr > p)
    return SN(si, md, p);
}

int SvToN(int a[8]) {
  LL pr = 0;
  for (LL i = 0; i < 8; i++) {
    pr = pr * 8 + a[i];
  }
  return SN(0, NN, pr);
}

void NToSv(int a[8], int n) {
  for (int i = 0; i < 8; i++) {
    a[i] = smps[n][i];
  }
}

void cng(int ip[8], int nxtv, int zp, int nz) {
  ip[zp] = ip[nz];
  ip[nz] = 0;
  int nv = SvToN(ip);
  if (nxtv < ckr[nv]) {
    ckr[nv] = nxtv;
    que.push(nv);
  }
  ip[nz] = ip[zp];
  ip[zp] = 0;
}

int main() {
  ckr = new int[N];
  smps = new int *[N];
  for (int i = 0; i < N; i++) {
    smps[i] = new int[8];
  }
  for (int i = 0; i < N; i++)
    ckr[i] = 100000000;

  int cnt = 0;
  do {
    for (int i = 0; i < 8; i++) {
      smps[cnt][i] = sample[i];
    }
    cnt++;
  } while (next_permutation(sample, sample + 8));
  NN = cnt;

  int ps[8] = {0, 1, 2, 3, 4, 5, 6, 7};
  int gl = SvToN(ps);
  que.push(gl);
  ckr[gl] = 0;

  while (que.size()) {
    int nw = que.front();
    que.pop();

    NToSv(ip, nw);
    int nxtv = ckr[nw] + 1;

    int zp = -1;
    while (ip[++zp] != 0)
      ;

    int nz = (zp + 4) % 8;
    cng(ip, nxtv, zp, nz);

    if (zp % 4 > 0) {
      cng(ip, nxtv, zp, zp - 1);
    }
    if (zp % 4 < 3) {
      cng(ip, nxtv, zp, zp + 1);
    }
  }

  while (1) {

    for (int i = 0; i < 8; i++) {
      if (scanf(" %d", &ip[i]) == EOF)
        return 0;
    }

    printf("%d\\n", ckr[SvToN(ip)]);
  }
  delete[] ckr;
  for (int i = 0; i < N; i++) {
    delete[] smps[i];
  }
  delete[] smps;

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cstdio>
#include <queue>
#include <utility>

#define N 40330

using namespace std;

typedef long long LL;

queue<int> que;
int *ckr;
int NN;

int ip[8];
int sample[8] = {0, 1, 2, 3, 4, 5, 6, 7};
int **smps;

int SN(int si, int ei, LL p) {
  LL pr = 0;
  int md = (si + ei) / 2;
  for (LL i = 0; i < 8; i++) {
    pr = pr * 8 + smps[md][i];
  }
  if (pr == p)
    return md;
  if (pr < p)
    return SN(md, ei, p);
  if (pr > p)
    return SN(si, md, p);
}

int SvToN(int a[8]) {
  LL pr = 0;
  for (LL i = 0; i < 8; i++) {
    pr = pr * 8 + a[i];
  }
  return SN(0, NN, pr);
}

void NToSv(int a[8], int n) {
  for (int i = 0; i < 8; i++) {
    a[i] = smps[n][i];
  }
}

void cng(int ip[8], int nxtv, int zp, int nz) {
  ip[zp] = ip[nz];
  ip[nz] = 0;
  int nv = SvToN(ip);
  if (nxtv < ckr[nv]) {
    ckr[nv] = nxtv;
    que.push(nv);
  }
  ip[nz] = ip[zp];
  ip[zp] = 0;
}

int main() {
  ckr = new int[N];
  smps = new int *[N];
  for (int i = 0; i < N; i++) {
    smps[i] = new int[8];
  }

  int cnt = 0;
  do {
    for (int i = 0; i < 8; i++) {
      smps[cnt][i] = sample[i];
    }
    cnt++;
  } while (next_permutation(sample, sample + 8));
  NN = cnt;

  while (1) {
    for (int i = 0; i < N; i++)
      ckr[i] = 100000000;
    for (int i = 0; i < 8; i++) {
      if (scanf(" %d", &ip[i]) == EOF)
        return 0;
    }

    int ps[8] = {0, 1, 2, 3, 4, 5, 6, 7};
    int gl = SvToN(ps);
    int ans = -1;

    int ipv = SvToN(ip);
    que.push(ipv);
    ckr[ipv] = 0;

    while (que.size()) {
      int nw = que.front();
      que.pop();

      if (gl == nw) {
        ans = ckr[nw];
        break;
      }

      NToSv(ip, nw);
      int nxtv = ckr[nw] + 1;

      int zp = -1;
      while (ip[++zp] != 0)
        ;

      int nz = (zp + 4) % 8;
      cng(ip, nxtv, zp, nz);

      if (zp % 4 > 0) {
        cng(ip, nxtv, zp, zp - 1);
      }
      if (zp % 4 < 3) {
        cng(ip, nxtv, zp, zp + 1);
      }
    }

    printf("%d\\n", ans);
  }
  delete[] ckr;
  for (int i = 0; i < N; i++) {
    delete[] smps[i];
  }
  delete[] smps;

  return 0;
}