问题描述
如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着。与空格子相邻的格子中的卡片可以移动到空格中。经过若干次移动,可以形成第二个图所示的局面。
我们把第一个图的局面记为:12345678.
把第二个图的局面记为:123.46758
显然是按从上到下,从左到右的顺序记录数字,空格记为句点。
本题目的任务是已知九宫的初态和终态,求最少经过多少步的移动可以到达。如果无论多少步都无法到达,则输出-1。
输入格式
输入第一行包含九宫的初态,第二行包含九宫的终态。
输出格式
输出最少的步数,如果不存在方案,则输出-1。
样例输入
12345678.
123.46758
样例输出
3
样例输入
13524678.
46758123.
样例输出
22
/*
* 132757 张燚 九宫重排 2014-03-08 21:56 5.209KB JAVA 正确 100 156ms 33.90MB 评测详情
*
*
*/
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Queue;
public class Main{//双向广搜
private static HashMap hm1=null,hm2=null;
public static void main(String[] args) {
BufferedReader bf=new BufferedReader(new InputStreamReader(System.in));
try {
String start=bf.readLine();
String end=bf.readLine();
char a[][]=new char[3][3];
char b[][]=new char[3][3];
int c=0;
int x1=0,y1=0,x2=0,y2=0;
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
a[i][j]=start.charAt(c);
b[i][j]=end.charAt(c);
if(a[i][j]=='.'){
x1=i;
y1=j;
}
if(b[i][j]=='.'){
x2=i;
y2=j;
}
c++;
}
}
Node node1=new Node(a,0,x1,y1);
Node node2=new Node(b,0,x2,y2);
Queue q1=new LinkedList();
Queue q2=new LinkedList();
hm1=new HashMap();
hm2=new HashMap();
hm1.put(start, 0);
hm2.put(end, 0);
q1.add(node1);
q2.add(node2);
System.out.println(bfs(q1,q2));
} catch (IOException e) {
e.printStackTrace();
}
}
private static int bfs(Queue q1,Queue q2) {
while(!q1.isEmpty()||!q2.isEmpty()){
if(!q1.isEmpty()){
Node node1=q1.poll();
// System.out.println(node1.getTuString()+"----1");
if(hm2.containsKey(node1.getTuString())){
return node1.getSum()+hm2.get(node1.getTuString());
}
int x=node1.getX();
int y=node1.getY();
if(x>0){
char a[][]=node1.getTuCopy();
a[x][y]=a[x-1][y];
a[x-1][y]='.';
Node n=new Node(a,node1.getSum()+1,x-1,y);
String s=n.getTuString();
if(hm2.containsKey(s)){
return n.getSum()+hm2.get(s);
}
if(!hm1.containsKey(s)){
hm1.put(s, n.getSum());
q1.add(n);
}
}
if(x<2){
char a[][]=node1.getTuCopy();
a[x][y]=a[x+1][y];
a[x+1][y]='.';
Node n=new Node(a,node1.getSum()+1,x+1,y);
String s=n.getTuString();
if(hm2.containsKey(s)){
return n.getSum()+hm2.get(s);
}
if(!hm1.containsKey(s)){
hm1.put(s, n.getSum());
q1.add(n);
}
}
if(y>0){
char a[][]=node1.getTuCopy();
a[x][y]=a[x][y-1];
a[x][y-1]='.';
Node n=new Node(a,node1.getSum()+1,x,y-1);
String s=n.getTuString();
if(hm2.containsKey(s)){
return n.getSum()+hm2.get(s);
}
if(!hm1.containsKey(s)){
hm1.put(s, n.getSum());
q1.add(n);
}
}
if(y<2){
char a[][]=node1.getTuCopy();
a[x][y]=a[x][y+1];
a[x][y+1]='.';
Node n=new Node(a,node1.getSum()+1,x,y+1);
String s=n.getTuString();
if(hm2.containsKey(s)){
return n.getSum()+hm2.get(s);
}
if(!hm1.containsKey(s)){
hm1.put(s, n.getSum());
q1.add(n);
}
}
}
if(!q2.isEmpty()){
Node node2=q2.poll();
// System.out.println(node2.getTuString()+"----2");
if(hm1.containsKey(node2.getTuString())){
return node2.getSum()+hm1.get(node2.getTuString());
}
int x=node2.getX();
int y=node2.getY();
if(x>0){
char a[][]=node2.getTuCopy();
a[x][y]=a[x-1][y];
a[x-1][y]='.';
Node n=new Node(a,node2.getSum()+1,x-1,y);
String s=n.getTuString();
if(hm1.containsKey(s)){
return n.getSum()+hm1.get(s);
}
if(!hm2.containsKey(s)){
hm2.put(s, n.getSum());
q2.add(n);
}
}
if(x<2){
char a[][]=node2.getTuCopy();
a[x][y]=a[x+1][y];
a[x+1][y]='.';
Node n=new Node(a,node2.getSum()+1,x+1,y);
String s=n.getTuString();
if(hm1.containsKey(s)){
return n.getSum()+hm1.get(s);
}
if(!hm2.containsKey(s)){
hm2.put(s, n.getSum());
q2.add(n);
}
}
if(y>0){
char a[][]=node2.getTuCopy();
a[x][y]=a[x][y-1];
a[x][y-1]='.';
Node n=new Node(a,node2.getSum()+1,x,y-1);
String s=n.getTuString();
if(hm1.containsKey(s)){
return n.getSum()+hm1.get(s);
}
if(!hm2.containsKey(s)){
hm2.put(s, n.getSum());
q2.add(n);
}
}
if(y<2){
char a[][]=node2.getTuCopy();
a[x][y]=a[x][y+1];
a[x][y+1]='.';
Node n=new Node(a,node2.getSum()+1,x,y+1);
String s=n.getTuString();
if(hm1.containsKey(s)){
return n.getSum()+hm1.get(s);
}
if(!hm2.containsKey(s)){
hm2.put(s, n.getSum());
q2.add(n);
}
}
}
}
return -1;
}
}
class Node{
char tu[][]=new char[3][3];
int sum=0;
int x=0,y=0;
public Node(char[][] tu, int sum, int x, int y) {
super();
this.tu = tu;
this.sum = sum;
this.x = x;
this.y = y;
}
public char[][] getTuCopy() {
char a[][]=new char[3][3];
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
a[i][j]=tu[i][j];
return a;
}
public String getTuString() {
StringBuffer sb=new StringBuffer("");
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
sb.append(tu[i][j]);
return sb.toString();
}
public void setTu(char[][] tu) {
this.tu = tu;
}
public int getSum() {
return sum;
}
public void setSum(int sum) {
this.sum = sum;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
}