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.ArrayDeque;
import java.util.HashMap;
import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		int[][] initial = {{0, 1, 2, 3}, {4, 5, 6, 7}};
		HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
		map.put(encode(initial), 0);
		ArrayDeque<int[][]> que = new ArrayDeque<int[][]>();
		que.add(initial);
		int[] dy = {0, -1, 0, 1};
		int[] dx = {-1, 0, 1, 0};
		
		while (!que.isEmpty()) {
			int[][] arr = que.remove();
			int y0 = 0, x0 = 0;
			for (int y = 0; y < 2; y++) {
				for (int x = 0; x < 4; x++) {
					if (arr[y][x] == 0) {
						y0 = y;
						x0 = x;
					}
				}
			}
			for (int i = 0; i < 4; i++) {
				int _y = y0 + dy[i], _x = x0 + dx[i];
				if (_y < 0 || _y >= 2 || _x < 0 || _x >= 4) {
					continue;
				}
				int[][] _arr = new int[2][4];
				for (int y = 0; y < 2; y++) {
					for (int x = 0; x < 4; x++) {
						_arr[y][x] = arr[y][x];
					}
				}
				_arr[y0][x0] = arr[_y][_x];
				_arr[_y][_x] = arr[y0][x0];
				if (!map.containsKey(encode(_arr))) {
					map.put(encode(_arr), map.get(encode(arr)) + 1);
					que.add(_arr);
				}
			}
		}
		
		Scanner in = new Scanner(System.in);
		while (in.hasNextInt()) {
			int[][] arr = new int[2][4];
			for (int y = 0; y < 2; y++) {
				for (int x = 0; x < 4; x++) {
					arr[y][x] = in.nextInt();
				}
			}
			System.out.println(map.get(encode(arr)));
		}
	}
	
	static int encode(int[][] arr) {
		int code = 0;
		for (int y = 0; y < 2; y++) {
			for (int x = 0; x < 4; x++) {
				code *= 8;
				code += arr[y][x];
			}
		}
		return code;
	}
}