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

public class Main {
	
	public static int hash(int ... nums){
		return (nums[0] << 21) + (nums[1] << 18) + (nums[2] << 15) + (nums[3] << 12) + (nums[4] << 9) + (nums[5] << 6) + (nums[6] << 3) + nums[7];
	}
	
	public static int swap(int h, int k){
		int from = 0;
		
		for(int i = 0; i < 8; i++){
			if(((h >> ((7 - i)*3)) & (0x0000000f >> 1)) == 0){
				from = i;
				break;
			}
		}
		
		int to = -1;
		
		switch(k){
		case 0: //hidari
			if(from % 4 == 0){
				break;
			}
			
			to = from - 1;
			break;
		case 1: //ue
			if((from / 4) == 0){
				break;
			}
			
			to = from - 4;
			break;
		case 2: //migi
			if(from % 4 == 3){
				break;
			}
			
			to = from + 1;
			break;
		case 3: //shita
			if(from / 4 == 1){
				break;
			}
			
			to = from + 4;
			break;
		}
		
		if(to == -1){
			return h;
		}
		
		int num = (h >> (7 - to)*3) & (0x0000000f >> 1);
		return h + (num << ((7 - from)*3)) - (num << ((7 - to)*3));
	}
	
	public static final int ANS = hash(0,1,2,3,4,5,6,7);
	
	public static void main(String[] args){
		
		LinkedList<Integer> list = new LinkedList<Integer>();
		HashMap<Integer,Integer> map = new HashMap<Integer,Integer>();
		list.add(ANS);
		map.put(ANS, 0);
		
		int step = 1;
		while(!list.isEmpty()){
			LinkedList<Integer> tmp_list = new LinkedList<Integer>();
			
			for(int hash_num : list){
				for(int i = 0; i < 4; i++){
					int new_hash = swap(hash_num,i);
					if(hash_num == new_hash){
						continue;
					}
					
					if(map.containsKey(new_hash)){
						continue;
					}
					
					map.put(new_hash, step);
					tmp_list.add(new_hash);
				}
			}
			
			list.clear();
			list.addAll(tmp_list);
			step++;
		}
		
		Scanner sc = new Scanner(System.in);
		
		
		while(sc.hasNext()){
			
			String str = sc.nextLine();
			
			String[] params = str.split(" ");
			int[] array = new int[params.length];
			for(int i = 0; i < params.length; i++){
				array[i] = Integer.parseInt(params[i]);
			}
			
			System.out.println(map.get(hash(array)));
			
		}
		
		
	}
	
}