Problem:
7 パズル

7 パズルは 8 つの正方形のカードとこれらのカードがぴたりと収まる枠で構成されています。それぞれのカードには、互いに区別できるように 0, 1, 2, ..., 7 と番号がつけられています。枠には、縦に 2 個、横に 4 個のカードを並べることができます。

7 パズルを始めるときには、まず枠にすべてのカードを入れます。枠のなかで 0 のカードだけは、上下左右に隣接するカードと位置を交換することができます。たとえば、枠の状態が図(a) のときに、0 のカードの右に隣接した、7 のカードと位置を交換すれば、図(b) の状態になります。あるいは、図(a) の状態から 0 のカードの下に隣接した 2 のカードと位置を交換すれば図(c) の状態になります。図(a) の状態で 0 のカードと上下左右に隣接するカードは 7 と 2 のカードだけなので、これ以外の位置の入れ替えは許されません。

ゲームの目的は、カードをきれいに整列して図(d) の状態にすることです。最初の状態を入力とし、カードをきれいに整列するまでに、必要な最小手数を出力するプログラムを作成してください。ただし、入力されたカードの状態からは図(d) の状態に移ることは可能であるとします。

入力データは、1 行に 8 つの数字が空白区切りで与えられます。これらは、最初の状態のカードの並びを表します。例えば、図(a) の数字表現は0 7 3 4 2 5 1 6 に、図(c) は 2 7 3 4 0 5 1 6 となります。

図(a) 0 7 3 4 2 5 1 6 の場合

図(b) 7 0 3 4 2 5 1 6 の場合

図(c) 2 7 3 4 0 5 1 6 の場合

図(d) 0 1 2 3 4 5 6 7 (最終状態)

Input

上記形式で複数のパズルが与えられます。入力の最後まで処理してください。
与えられるパズルの数は 1,000 以下です。

Output

各パズルについて、最終状態へ移行する最小手数を１行に出力してください。

Sample Input

0 1 2 3 4 5 6 7
1 0 2 3 4 5 6 7
7 6 5 4 3 2 1 0

Output for the Sample Input

0
1
28

Solution in C++ (judge verdict: Time Limit Exceeded)

#include <iostream>
#include <queue>
#include <vector>
#include <map>
#include <algorithm>
 
using namespace std;
 
typedef vector<int> V;
typedef queue<V> QV;
typedef queue<int> QI;
 
int fact(int n) {
    int f = 1;
    for (int i = 1; i <= n; ++i) {
        f *= i;
    }
    return f;
}
 
int v2i(V &v) {
    int n = 0;
    int f = fact(8);
    bool is_used[8];
    for (int i = 0; i < 8; ++i) {
        is_used[i] = false;
    }
    for (int i = 0; i < 8; ++i) {
        f /= 8 - i;
        int count = 0;
        for (int j = 0; j < v[i]; ++j) {
            if (!is_used[j]) {
                ++count;
            }
        }
        n += count * f;
        is_used[v[i]] = true;
    }
    return n;
}
 
int solve(int puzzle[]) {
    V p(8);
    QV q;
    QI qi;
    int min_count[40320];
    int zi;
    for (int i = 0; i < 8; ++i) {
        p[i] = puzzle[i];
    }
    for (int i = 0; i < 40320; ++i) {
        min_count[i] = 1e9;
    }
    q.push(p);
    qi.push(v2i(p));
    min_count[qi.front()] = 0;
    while (!q.empty()) {
        V p = q.front();
        int n = qi.front();
        q.pop();
        qi.pop();
        if (n == 0) {
            return min_count[0];
        }
        zi = 0;
        while (p[zi] != 0) {
            ++zi;
        }
        if (zi != 0 && zi != 4) {
            V p2 = p;
            swap(p2[zi], p2[zi - 1]);
            int n2 = v2i(p2);
            if (min_count[n2] > min_count[n] + 1) {
                min_count[n2] = min_count[n] + 1;
                q.push(p2);
                qi.push(n2);
            }
        }
        if (zi != 3 && zi != 7) {
            V p2 = p;
            swap(p2[zi], p2[zi + 1]);
            int n2 = v2i(p2);
            if (min_count[n2] > min_count[n] + 1) {
                min_count[n2] = min_count[n] + 1;
                q.push(p2);
                qi.push(n2);
            }
        }
        if (zi < 4) {
            V p2 = p;
            swap(p2[zi], p2[zi + 4]);
            int n2 = v2i(p2);
            if (min_count[n2] > min_count[n] + 1) {
                min_count[n2] = min_count[n] + 1;
                q.push(p2);
                qi.push(n2);
            }
        } else {
            V p2 = p;
            swap(p2[zi], p2[zi - 4]);
            int n2 = v2i(p2);
            if (min_count[n2] > min_count[n] + 1) {
                min_count[n2] = min_count[n] + 1;
                q.push(p2);
                qi.push(n2);
            }
        }
    }
    return -1;
}
 
int main() {
    int puzzle[8];
    while (true) {
        for (int i = 0; i < 8; ++i) {
            cin >> puzzle[i];
        }
        cout << solve(puzzle) << endl;
    }
}