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

class Main {
	public static void main(String[] args) throws IOException {
		Scanner in = new Scanner(System.in);
		while(in.hasNext()) {
			String[] map = in.nextLine().split(" ");
			System.out.println(solve(map));
		}
	}

	public static int solve(String[] map) {
		Set<Integer> s = new HashSet<>();
		Queue<Node> q = new PriorityQueue<>();
		int z_pos = 0;
		for(int i=0;i<8;i++) {
			if(map[i].equals("0")) {
				z_pos = i;break;
			}
		}
		q.offer(new Node(z_pos, 0, map));
		while(!q.isEmpty()) {
			Node node = q.poll();
			int id = node.getId();
			s.add(id);

			// ??????
			if(id == 1234567) {
				return node.num;
			}

			// ??????????????????????????\??????????????????????????\????????????
			int di[] = {-4, +4, -1, +1};
			for(int i=0;i<4;i++) {
				int zero = node.zero_pos + di[i];
				// ???????????????
				if(zero < 0 || zero > 7) continue;

				// ??\????????????
				Node newNode = new Node(zero, node.num+1, node.map);
				swap(newNode.map, node.zero_pos, zero);
				if(s.contains(newNode.getId())) continue;

				q.offer(newNode);
				s.add(newNode.getId());
			}
		}

		return -1;
	}

	public static void swap(String[] map, int p1, int p2) {
		String buf = map[p1];
		map[p1] = map[p2];
		map[p2] = buf;
	}
}

class Node implements  Comparable<Node>{
	int zero_pos = 0;
	int num;
	String[] map;
	Node(int zero_pos, int num, String[] map) {
		this.zero_pos = zero_pos;
		this.num = num;
		this.map = map.clone();
	}

	public int getId() {
		int id = 0;
		for(int i=0;i<map.length;i++) {
			id = id * 10 + Integer.parseInt(map[i]);
		}
		return id;
	}

	@Override
	public int compareTo(Node o) {
		return this.num - o.num;
	}
}