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

import java.io.*;
import java.lang.*;
import java.util.Scanner;
import java.util.Arrays;

class State {
    public int map = 0;
    public State nextState[] = new State[4];
	public boolean isEndState(){
		return (this.map == 0xFAC688);
	}
	public void extendTree(){
		int i;
		if(this.hasChild()){
			for(i = 0; i < 4; i++){
				if(this.nextState[i] != null){
					this.nextState[i].extendTree();
				}
			}
			this.cutBranch(this.map);
			return;
		}
		int p0x = 0, p0y = 0;
		for(i = 0; i < 8; i++){
			if(((this.map >>> (i * 3)) & 7) == 0){
				p0x = i % 4;
				p0y = i / 4;
				break;
			}
		}
		if(i == 8){
			return;
		}
		if(p0y == 1){
			this.nextState[0] = new State();
			this.nextState[0].copyFrom(this.map);
			this.nextState[0].exchange(p0x, 0, p0x, 1);
		}
		if(p0x != 3){
			this.nextState[1] = new State();
			this.nextState[1].copyFrom(this.map);
			this.nextState[1].exchange(p0x, p0y, p0x + 1, p0y);
		}
		if(p0y == 0){
			this.nextState[2] = new State();
			this.nextState[2].copyFrom(this.map);
			this.nextState[2].exchange(p0x, 0, p0x, 1);
		}
		if(p0x != 0){
			this.nextState[3] = new State();
			this.nextState[3].copyFrom(this.map);
			this.nextState[3].exchange(p0x, p0y, p0x - 1, p0y);
		}
	}
	public boolean hasChild(){
		int i;
		for(i = 0; i < 4; i++){
			if(this.nextState[i] != null){
				return true;
			}
		}
		return false;
	}
	public void copyFrom(int src){
		this.map = src;
	}
	public void printMap(){
		int i;
		System.out.println(Integer.toHexString(this.map));
		for(i = 0; i < 4; i++){
			System.out.print(((this.map >>> (i * 3)) & 7) + " ");
		}
		System.out.println();
		for(i = 4; i < 8; i++){
			System.out.print(((this.map >>> (i * 3)) & 7) + " ");
		}
		System.out.println();
		System.out.println();
	}
	public void exchange(int px, int py, int qx, int qy){
		int p, q;
		p = ((this.map >>> ((py * 4 + px) * 3)) & 7);
		q = ((this.map >>> ((qy * 4 + qx) * 3)) & 7);
		this.map &= ~(7 << ((py * 4 + px) * 3));
		this.map |= q << ((py * 4 + px) * 3);
		this.map &= ~(7 << ((qy * 4 + qx) * 3));
		this.map |= p << ((qy * 4 + qx) * 3);
	}
	public boolean hasEndState(){
		int i;
		if(this.hasChild()){
			for(i = 0; i < 4; i++){
				if(this.nextState[i] != null && this.nextState[i].hasEndState()){
					return true;
				}
			}
			return false;	
		}
		return this.isEndState();
	}
	public int cutBranch(int map){
		int i, flg = 0;
		if(this.hasChild()){
			for(i = 0; i < 4; i++){
				if(this.nextState[i] != null){
					if(this.nextState[i].cutBranch(map) == 1){
						flg |= 1 << i;
						this.nextState[i] = null;
					}
				} else{
					flg |= 1 << i;
				}
			}
			if(flg == 0x0f){
				return 1;
			}
			return 0;
		}
		if(this.map == map){
			return 1;
		}
		return 0;
	}
}

public class Main {
	public static void main(String[] args){
		InputStreamReader isr = new InputStreamReader(System.in);
		BufferedReader br = new BufferedReader(isr);
		String buf;
		try {
			for(;;){
				State rootState = new State();
				buf = br.readLine();
				if(buf == null){
					break;
				}
				Scanner scanner = new Scanner(buf);
				if(!scanner.hasNext()){
					break;
				}
				int i;
				int initState = 0;
				for(i = 0; i < 8; i++){
					initState |= scanner.nextByte() << (i * 3);
				}
				rootState.copyFrom(initState);
				for(i = 0; ; i++){
					if(rootState.hasEndState()){
						System.out.println(i);
						break;
					}
					rootState.extendTree();
					//System.out.println(Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory());
				}

			}
		}
		catch(IOException e) {
			System.out.println("Read error.");
			return;
		}
	}
}