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.util.*;

public class Main{
	static byte[] done;
	static LinkedList<int[][]> pats;
	static ArrayDeque<Integer> steps;
	static int Goal = 1234567;
	static int ans;
	static final int[] dx = {1,0,-1,0};
	static final int[] dy = {0,1,0,-1};
	static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	
	public static void main(String[] args) throws IOException {
		
		String str;
		while((str = br.readLine()) != null){
			if(str.equals("")) break;
			done = new byte[76543211];
			pats = new LinkedList<int[][]>();
			steps = new ArrayDeque<Integer>();
			
			String input[] = str.split(" +");
			int nana[][] = new int[2][4];
			int id = 0;
			
			for(int x = 0; x < 2; x++)
				for(int y = 0; y < 4; y++)
					nana[x][y] = new Integer(input[id++]);
			
			pats.add(nana);
			done[toNum(nana)] = 1;
			steps.add(0);
			
			while(!pats.isEmpty()){
				
				int[][] pattern = pats.poll();
				int step = steps.poll();

				if(toNum(pattern) == Goal){
					ans = step;
					break;
				}
				
				int sx = -1, sy = -1;
				id = 0;
				for(int p = 0; p < 2; p++)
					for(int q = 0; q < 4; q++)
						if(pattern[p][q] == 0){
							sy = p;
							sx = q;
						}
				
				for(int i = 0; i < 4; i++){
					if(sx+dx[i]<0 | sx+dx[i]>=4) continue;
					if(sy+dy[i]<0 | sy+dy[i]>=2) continue;
					pattern[sy][sx] = pattern[sy+dy[i]][sx+dx[i]];
					pattern[sy+dy[i]][sx+dx[i]] = 0;
					
					int num = toNum(pattern);
					if(done[num]==0){
						done[num]=1;
						pats.add(FullClone(pattern));
						steps.add(step+1);
					}
					pattern[sy+dy[i]][sx+dx[i]] = pattern[sy][sx];
					pattern[sy][sx] = 0;
				}
			}
			System.out.println(ans);
		}
	}
	
	private static int[][] FullClone(int[][] pattern) {
		int[][] cl = new int[2][4];
		for(int p = 0; p < 2; p++)
			for(int q = 0; q < 4; q++)
				cl[p][q] = pattern[p][q];
		return cl;
	}

	static int toNum(int str[][]){
		String s = "";
		for(int i = 0; i < 2; i++)
			for(int j = 0; j < 4; j++)
				s += str[i][j]+"";
		return new Integer(s);
	}
}