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

#include <iostream>
#include <map>
#include <queue>
#include <set>

using namespace std;

map<unsigned int, int> dist;

unsigned int change(unsigned short stage[4][2]) {
  return stage[0][0] + stage[1][0] * 10 + stage[2][0] * 100 +
         stage[3][0] * 1000 + stage[0][1] * 10000 + stage[1][1] * 100000 +
         stage[2][1] * 1000000 + stage[3][1] * 10000000;
}

void reverse_change(unsigned short stage[4][2], int data) {
  stage[3][1] = data / 10000000;
  data -= stage[3][1] * 10000000;
  stage[2][1] = data / 1000000;
  data -= stage[2][1] * 1000000;
  stage[1][1] = data / 100000;
  data -= stage[1][1] * 100000;
  stage[0][1] = data / 10000;
  data -= stage[0][1] * 10000;
  stage[3][0] = data / 1000;
  data -= stage[3][0] * 1000;
  stage[2][0] = data / 100;
  data -= stage[2][0] * 100;
  stage[1][0] = data / 10;
  data -= stage[1][0] * 10;
  stage[0][0] = data;
  data -= stage[0][0];
}

bool move(unsigned short target[4][2], unsigned int u, int b) {
  unsigned short stage[4][2];
  int x, y;

  reverse_change(stage, u);
  for (int i = 0; i < 2; i++) {
    for (int j = 0; j < 4; j++) {
      if (stage[j][i] == 0) {
        x = j;
        y = i;
        goto A;
      }
    }
  }
A:
  int dx, dy;

  dx = x;
  dy = y;
  switch (b) {
  case 0:
    dx++;
    if (dx > 3)
      return true;
    break;
  case 1:
    dx--;
    if (dx < 0)
      return true;
    break;
  case 2:
    dy++;
    if (dy > 1)
      return true;
    break;
  case 3:
    dy--;
    if (dy < 0)
      return true;
    break;
  }

  unsigned short a;
  a = stage[x][y];
  stage[x][y] = stage[dx][dy];
  stage[dx][dy] = a;

  for (int i = 0; i < 2; i++) {
    for (int j = 0; j < 4; j++) {
      target[j][i] = stage[j][i];
    }
  }

  return false;
}

int bfs(unsigned short stage[4][2]) {
  set<unsigned int> history;
  queue<unsigned int> q;

  dist[change(stage)] = 0;

  q.push(change(stage));
  while (!q.empty()) {
    unsigned int u = q.front();

    for (int i = 0; i < 4; i++) {
      unsigned short v[4][2];
      if (move(v, u, i))
        continue;
      unsigned int hoge = change(v);
      if (history.count(hoge))
        continue;
      dist[hoge] = dist[u] + 1;
      history.insert(hoge);
      q.push(hoge);
    }

    q.pop();
  }
  return -1;
}

int main(int argc, char const *argv[]) {
  unsigned short stage[4][2];

  reverse_change(stage, 76543210);
  bfs(stage);
  dist[change(stage)] = 0;

  while (cin >> stage[0][0] >> stage[1][0] >> stage[2][0] >> stage[3][0] >>
         stage[0][1] >> stage[1][1] >> stage[2][1] >> stage[3][1]) {
    cout << dist[change(stage)] << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <iostream>
#include <map>
#include <queue>
#include <set>

using namespace std;

unsigned int change(unsigned short stage[4][2]) {
  return stage[0][0] + stage[1][0] * 10 + stage[2][0] * 100 +
         stage[3][0] * 1000 + stage[0][1] * 10000 + stage[1][1] * 100000 +
         stage[2][1] * 1000000 + stage[3][1] * 10000000;
}

void reverse_change(unsigned short stage[4][2], int data) {
  stage[3][1] = data / 10000000;
  data -= stage[3][1] * 10000000;
  stage[2][1] = data / 1000000;
  data -= stage[2][1] * 1000000;
  stage[1][1] = data / 100000;
  data -= stage[1][1] * 100000;
  stage[0][1] = data / 10000;
  data -= stage[0][1] * 10000;
  stage[3][0] = data / 1000;
  data -= stage[3][0] * 1000;
  stage[2][0] = data / 100;
  data -= stage[2][0] * 100;
  stage[1][0] = data / 10;
  data -= stage[1][0] * 10;
  stage[0][0] = data;
  data -= stage[0][0];
}

bool move(unsigned short target[4][2], unsigned int u, int b) {
  unsigned short stage[4][2];
  int x, y;

  reverse_change(stage, u);
  for (int i = 0; i < 2; i++) {
    for (int j = 0; j < 4; j++) {
      if (stage[j][i] == 0) {
        x = j;
        y = i;
        goto A;
      }
    }
  }
A:
  int dx, dy;

  dx = x;
  dy = y;
  switch (b) {
  case 0:
    dx++;
    break;
  case 1:
    dx--;
    break;
  case 2:
    dy++;
    break;
  case 3:
    dy--;
    break;
  }

  if (dx < 0 || dy < 0 || dx > 3 || dy > 1)
    return true;

  unsigned short a;
  a = stage[x][y];
  stage[x][y] = stage[dx][dy];
  stage[dx][dy] = a;

  for (int i = 0; i < 2; i++) {
    for (int j = 0; j < 4; j++) {
      target[j][i] = stage[j][i];
    }
  }

  return false;
}

int bfs(unsigned short stage[4][2]) {
  map<unsigned int, int> dist;
  set<unsigned int> history;
  queue<unsigned int> q;

  dist[change(stage)] = 0;

  q.push(change(stage));
  while (!q.empty()) {
    unsigned int u = q.front();
    if (u == 76543210)
      return dist[u];

    for (int i = 0; i < 4; i++) {
      unsigned short v[4][2];
      if (move(v, u, i))
        continue;
      unsigned int hoge = change(v);
      if (history.count(hoge))
        continue;
      dist[hoge] = dist[u] + 1;
      history.insert(hoge);
      q.push(hoge);
    }

    q.pop();
  }
  return -1;
}

int main(int argc, char const *argv[]) {
  unsigned short stage[4][2];

  while (cin >> stage[0][0] >> stage[1][0] >> stage[2][0] >> stage[3][0] >>
         stage[0][1] >> stage[1][1] >> stage[2][1] >> stage[3][1]) {
    cout << bfs(stage) << endl;
  }
  return 0;
}