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++14 (judge verdict: Accepted)

#include<iostream>
#include<vector>
#include<queue>
#include<map>
#include<string>
#include<algorithm>

using namespace std;

map<vector<int>, int> memo;
queue<vector<int>> que;
const int vec[4] = { -1,1,4,-4 };

vector<int> makev(vector<int> tv) {
	vector<int> ans(8);
	for (int i = 0; i < 8; i++)ans[i] = tv[i];
	return ans;
}

int main() {
	memo[{0, 1, 2, 3, 4, 5, 6, 7}] = 0;
	que.push({ 0,1,2,3,4,5,6,7,0 });
	while (que.size()) {
		vector<int> tv = que.front();
		que.pop();
		int zeropos;
		for (int i = 0; i < 8; i++)if (tv[i] == 0)zeropos = i;
		for (int i = 0; i < 4; i++) {
			if (i < 2) {//??????
				if (zeropos + vec[i] < 0 || zeropos + vec[i] > 7)continue;
				if ((zeropos == 3 && zeropos + vec[i] == 4) || (zeropos == 4 && zeropos + vec[i] == 3))continue;
				vector<int> tmpv = tv;
				tmpv[8]++;
				swap(tmpv[zeropos], tmpv[zeropos + vec[i]]);
				if (memo.count(makev(tmpv)) == 0) {
					memo[makev(tmpv)] = tmpv[8], que.push(tmpv);
				}
			}
			else {//??????
				if (zeropos + vec[i] < 0 || zeropos + vec[i] > 7)continue;
				vector<int> tmpv = tv;
				tmpv[8]++;
				swap(tmpv[zeropos], tmpv[zeropos + vec[i]]);
				if (memo.count(makev(tmpv)) == 0) {
					memo[makev(tmpv)] = tmpv[8], que.push(tmpv);
				}
			}
		}
	}
	vector<int> input(8);
	while (cin >> input[0] >> input[1] >> input[2] >> input[3] >> input[4] >> input[5] >> input[6] >> input[7]) {
		cout << memo[input] << endl;
	}
	return 0;
}