九宫重排
time limit per test 1 second memory limit per test 256 megabytes
问题描述
  如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着。与空格子相邻的格子中的卡片可以移动到空格中。经过若干次移动,可以形成第二个图所示的局面。

  我们把第一个图的局面记为:12345678.
  把第二个图的局面记为:123.46758
  显然是按从上到下,从左到右的顺序记录数字,空格记为句点。
  本题目的任务是已知九宫的初态和终态,求最少经过多少步的移动可以到达。如果无论多少步都无法到达,则输出-1。
输入格式
  输入第一行包含九宫的初态,第二行包含九宫的终态。
输出格式
  输出最少的步数,如果不存在方案,则输出-1。
样例输入
12345678.
123.46758
样例输出
3
样例输入
13524678.
46758123.
样例输出
22

题解

能够一眼看出是bfs,就是状态该怎么保存是个问题 一开始用HashSet保存字符串表示状态超时了 所以选择用双重bfs 即同时从开始和结束点开始bfs 用map记录状态和到达它的最小步数 每次弹出时判断另一个map中是否存在,存在的话两个次数相加就是答案
## AC code:(不包含输入类)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
import java.io.*;  
import java.util.*;
import java.util.concurrent.LinkedBlockingQueue;
public class Main {
static int result;
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
PrintWriter pw= new PrintWriter(System.out);
while(sc.hasNext()){
String s=sc.next();
String e=sc.next();
if(bfs(s,e))pw.println(result);
else pw.println(-1);
pw.flush();
}
}
static boolean bfs(String s,String e){
LinkedBlockingQueue<Node>queues=new LinkedBlockingQueue();
HashMap<String,Integer>maps=new HashMap<String,Integer>();
HashMap<String,Integer>mape=new HashMap<String,Integer>();
LinkedBlockingQueue<Node>queuee=new LinkedBlockingQueue();
queues.add(new Node(s,0));
queuee.add(new Node(e,0));
maps.put(s, 0);
mape.put(e, 0);
while(!queues.isEmpty()||!queuee.isEmpty()){
StringBuilder sb;
if(!queues.isEmpty()){
Node temps=queues.poll();
if(mape.containsKey(temps.s)){
result=mape.get(temps.s)+temps.count;
return true;
}
int indexs=-1;
for(int i=0;i<temps.s.length();i++){
if(temps.s.charAt(i)=='.') indexs=i;
}
int left=left(indexs);
int right=right(indexs);
int up=up(indexs);
int down=down(indexs);

if(left!=-1){
sb=new StringBuilder(temps.s);
sb.setCharAt(indexs,temps.s.charAt(left));
sb.setCharAt(left,'.');
String t=sb.toString();
if(!maps.containsKey(t)){
queues.add(new Node(t,temps.count+1));
maps.put(t,temps.count+1);
}
}
if(right!=-1){
sb=new StringBuilder(temps.s);
sb.setCharAt(indexs,temps.s.charAt(right));
sb.setCharAt(right,'.');
String t=sb.toString();
if(!maps.containsKey(t)){
queues.add(new Node(t,temps.count+1));
maps.put(t,temps.count+1);
}
}
if(up!=-1){
sb=new StringBuilder(temps.s);
sb.setCharAt(indexs,temps.s.charAt(up));
sb.setCharAt(up,'.');
String t=sb.toString();
if(!maps.containsKey(t)){
queues.add(new Node(t,temps.count+1));
maps.put(t,temps.count+1);
}
}
if(down!=-1){
sb=new StringBuilder(temps.s);
sb.setCharAt(indexs,temps.s.charAt(down));
sb.setCharAt(down,'.');
String t=sb.toString();
if(!maps.containsKey(t)){
queues.add(new Node(t,temps.count+1));
maps.put(t,temps.count+1);
}
}
}

if(!queuee.isEmpty()){
Node tempe=queuee.poll();
if(maps.containsKey(tempe.s)){
result=maps.get(tempe.s)+tempe.count;
return true;
}
int indexe=-1;
for(int i=0;i<tempe.s.length();i++){
if(tempe.s.charAt(i)=='.') indexe=i;
}
int lefte=left(indexe);
int righte=right(indexe);
int upe=up(indexe);
int downe=down(indexe);

if(lefte!=-1){
sb=new StringBuilder(tempe.s);
sb.setCharAt(indexe,tempe.s.charAt(lefte));
sb.setCharAt(lefte,'.');
String t=sb.toString();
if(!mape.containsKey(t)){
queuee.add(new Node(t,tempe.count+1));
mape.put(t,tempe.count+1);
}
}
if(righte!=-1){
sb=new StringBuilder(tempe.s);
sb.setCharAt(indexe,tempe.s.charAt(righte));
sb.setCharAt(righte,'.');
String t=sb.toString();
if(!mape.containsKey(t)){
queuee.add(new Node(t,tempe.count+1));
mape.put(t,tempe.count+1);
}
}
if(upe!=-1){
sb=new StringBuilder(tempe.s);
sb.setCharAt(indexe,tempe.s.charAt(upe));
sb.setCharAt(upe,'.');
String t=sb.toString();
if(!mape.containsKey(t)){
queuee.add(new Node(t,tempe.count+1));
mape.put(t,tempe.count+1);
}
}
if(downe!=-1){
sb=new StringBuilder(tempe.s);
sb.setCharAt(indexe,tempe.s.charAt(downe));
sb.setCharAt(downe,'.');
String t=sb.toString();
if(!mape.containsKey(t)){
queuee.add(new Node(t,tempe.count+1));
mape.put(t,tempe.count+1);
}
}
}
}
return false;
}
static int left(int index){
if(index==0||index==3||index==6) return -1;
else return index-1;
}
static int up(int index){
if(index==0||index==1||index==2) return -1;
else return index-3;
}
static int right(int index){
if(index==2||index==5||index==8) return -1;
else return index+1;
}
static int down(int index){
if(index==6||index==7||index==8) return -1;
else return index+3;
}
}
class Node{
String s;
int count;
Node(String s,int t){
this.s=s;
this.count=t;
}
}