如图1的九宫格中,放着 1~8 的数字卡片,还有一个格子空着。与空格子相邻的格子中的卡片可以移动到空格中。经过若干次移动,可以形成图2所示的局面。
我们把图1的局面记为:12345678.
把图2的局面记为:123.46758
显然是按从上到下,从左到右的顺序记录数字,空格记为句点。
本题目的任务是已知九宫的初态和终态,求最少经过多少步的移动可以到达。
如果无论多少步都无法到达,则输出-1。
例如:
输入数据为:
12345678.
123.46758
则程序应该输出:
3
再如:
输入:
13524678.
46758123.
则,程序输出:
22
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
import java.util.concurrent.LinkedBlockingQueue;
public class lanqiao2012_final_4 {
public static String Start;//开始的字符串
public static String end;//结束的字符串
public static int dep = 1;
public static class Node{
public Node(String str, int pos, int dep) {
this.val = str;
this.position = pos;
this.depth = dep;
}
String val;//保存字符串
int position; //保存'.'位置
int depth;//保存深度
@Override
public String toString() {
return "Node [val=" + val + ", position=" + position + ", depth="
+ depth + "]";
}
}
public static String change(String str,int postion1,int postion2){
StringBuilder sb = new StringBuilder(str);
char ch1 = sb.charAt(postion1);
char ch2 = sb.charAt(postion2);
sb.setCharAt(postion2, ch1);
sb.setCharAt(postion1, ch2);
return sb.toString();
}
public static int bfs(String str){
int len = str.length()-1;
Queue<Node> que = new LinkedList<Node>();//创建一个队列 用来发曾经遍历过的状态
HashSet<String> hs = new HashSet<String>();//创建一个hashset用来判断这个状态是否已经遍历过
int pos = 0;
for(int i=0;i<str.length();i++){//找到.的位置
if(str.charAt(i)=='.'){
pos = i;
break;
}
}
if(pos-3>=0){
que.add(new Node(change(str,pos-3,pos),pos-3,dep));//保存交换后的字符,.的位置 深度
hs.add(change(str,pos-3,pos));
}
if(pos+3<=len){
que.add(new Node(change(str,pos+3,pos),pos+3,dep));//
hs.add(change(str,pos+3,pos));
}
if(pos%3<2){
que.add(new Node(change(str,pos+1,pos),pos+1,dep));
hs.add(change(str,pos+1,pos));
}
if(pos%3==1||pos%3==2){
que.add(new Node(change(str,pos-1,pos),pos-1,dep));
hs.add(change(str,pos-1,pos));
}
while(!que.isEmpty()){//需要判断重复走过的路,减枝
Node p = que.poll();
if(p.val.equals(end)) return p.depth;
int ps = p.position;
if(ps-3>=0){
if(!hs.contains(change(p.val,ps-3,ps)))
que.add(new Node(change(p.val,ps-3,ps),ps-3,p.depth+1));//保存交换后的字符,.的位置 深度
}
if(ps+3<=len){
if(!hs.contains(change(p.val,ps+3,ps)))
que.add(new Node(change(p.val,ps+3,ps),ps+3,p.depth+1));//
}
if(ps%3<2){
if(!hs.contains(change(p.val,ps+1,ps)))
que.add(new Node(change(p.val,ps+1,ps),ps+1,p.depth+1));
}
if(ps%3==1||ps%3==2){
if(!hs.contains(change(p.val,ps-1,ps)))
que.add(new Node(change(p.val,ps-1,ps),ps-1,p.depth+1));
}
}
return -1;
}
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
Start = s.nextLine();
end = s.nextLine();
System.out.println(bfs(Start));
}
}