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

import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

public class Main {
	static final int MAX_NUM = 76543210;

	void run() {
		Scanner scan = new Scanner(System.in);
		char[] ans = new char[MAX_NUM + 1];
		Queue<char[]> que = new LinkedList<char[]>();
		que.add(new char[] { 0, 1, 2, 3, 4, 5, 6, 7 });
		while (!que.isEmpty()) {
			int size = que.size();
			for (int i = 0; i < size; i++) {
				char[] p = que.poll();
				int num = convertArrayToNumber(p);
				int index = getZeroOfIndex(p);
				int[] d = { -4, -1, 1, 4 };
				for (int j = 0; j < d.length; j++) {
					int ni = index + d[j];
					if (ni < 0 || ni >= 8)
						continue;
					if (index == 4 && d[j] == -1)
						continue;
					if (index == 3 && d[j] == 1)
						continue;
					char[] np = p.clone();
					swap(np, ni, index);
					int n = convertArrayToNumber(np);
					if (ans[n] != 0)
						continue;
					if (ans[n] == 0 && n == 1234567) continue;
					ans[n] = (char)(ans[num] + 1);
					que.add(np);
				}
			}
		}
		while (scan.hasNext()) {
			char[] pazzle = new char[8];
			for (int i = 0; i < 8; i++) {
				pazzle[i] = (char)scan.nextInt();
			}
			System.out.println((int)ans[convertArrayToNumber(pazzle)]);
		}
	}

	void swap(char[] array, int a, int b) {
		char tmp = array[a];
		array[a] = array[b];
		array[b] = tmp;
	}

	int convertArrayToNumber(char[] array) {
		int sum = 0;
		for (int i = 1; i <= 8; i++) {
			sum += array[i - 1] * Math.pow(10, 8 - i);
		}
		return sum;
	}

	int getZeroOfIndex(char[] array) {
		for (int i = 0; i < array.length; i++) {
			if (array[i] == 0)
				return i;
		}
		return -1;
	}

	public static void main(String[] args) {
		new Main().run();
	}
}