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: Time Limit Exceeded)

import java.util.*;

public class Main{
	public static void main(String[] args){
		Scanner sc = new Scanner(System.in);

		while(sc.hasNextInt()){
			int[] t = new int[8];
			int[] g = new int[8];
			for(int i=0;i<8;i++){
				t[i] = sc.nextInt();
				g[i] = i;
			}

			Queue<State> open = new LinkedList<State>();
			HashSet<State> closed = new HashSet<State>();
			ArrayList<State> closedList = new ArrayList<State>();

			int ans = -1;
			open.add(new State(0,t,false));
			open.add(new State(0,g,true));

			while(!open.isEmpty()){
				State st = open.poll();

				if(closed.contains(st)){
					int idx = closedList.indexOf(st);
					State tmp = closedList.get(idx);

					if(tmp.d != st.d){
						ans = tmp.cost + st.cost;
						break;
					}
					else{
						continue;
					}
				}
				closed.add(st);
				closedList.add(st);

				open.addAll(st.nexts());
			}

			System.out.println(ans);
		}
	}
}

class State{
	int cost;
	int[] t;
	boolean d;

	State(int cost,int[] t,boolean d){
		this.cost = cost;
		this.t = new int[8];
		for(int i=0;i<8;i++) this.t[i] = t[i];
		this.d = d;
	}

	List<State> nexts(){
		int idx = -1;
		for(idx=0;t[idx]!=0;idx++);

		List<State> sts = new ArrayList<State>();
		if(idx >= 4){
			State st = new State(cost,t,d);
			st.t[idx-4] ^= st.t[idx];
			st.t[idx] ^= st.t[idx-4];
			st.t[idx-4] ^= st.t[idx];
			st.cost++;
			sts.add(st);
		}
		if(idx < 4){
			State st = new State(cost,t,d);
			st.t[idx+4] ^= st.t[idx];
			st.t[idx] ^= st.t[idx+4];
			st.t[idx+4] ^= st.t[idx];
			st.cost++;
			sts.add(st);
		}
		if(idx%4 > 0){
			State st = new State(cost,t,d);
			st.t[idx-1] ^= st.t[idx];
			st.t[idx] ^= st.t[idx-1];
			st.t[idx-1] ^= st.t[idx];
			st.cost++;
			sts.add(st);
		}
		if(idx%4 < 3){
			State st = new State(cost,t,d);
			st.t[idx+1] ^= st.t[idx];
			st.t[idx] ^= st.t[idx+1];
			st.t[idx+1] ^= st.t[idx];
			st.cost++;
			sts.add(st);
		}

		return sts;
	}

	public boolean equals(Object o){
		State st = (State)o;
		for(int i=0;i<8;i++) if(t[i] != st.t[i]) return false;
		return true;
	}

	public int hashCode(){
		int res = 0;
		for(int i=0;i<8;i++) res += t[i] * Math.pow(10,i);
		return res;
	}
}