这道题是Acwing上面845题. 八数码
是一道bfs的扩展应用。这道题主要是你能够把整个二维数组抽象成一个string, 然后通过charArray来进行bfs,也就是四个方向的扩展。每次交换之后加入到当前的队列,之后换回来,这样才能够保证你这次交换不会影响后面的尝试(也就是不是一条路走到黑)。但注意这里写代码的一定要注意,当你把队列里面的string拿出来变成char array 之后,你在交换字母的时候一定不能把这个char array 写成java char[] arr = cur.toCharArray(); arr.toString()
注意这样就会出bug!因为如果把array 变成string之后,那么你当前这个array就会改动,然后你在想从之前的x ,y点获取新坐标的时候就会出错。
总之这个bug看了我好久我都不知道怎么回事,因为之前都没问题,今天把array 改成array.toString()
之后就出现了这个bug,以后一定要注意。
import java.io.*;
import java.util.*;
public class Main {
static int[][] dirs = new int[][] {{0,1}, {0, -1}, {1,0}, {-1,0}};
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] s1 = br.readLine().split(" ");
StringBuilder sb = new StringBuilder();
for (String s : s1) sb.append(s);
// System.out.println(sb.toString());
int res = bfs(sb.toString());
System.out.print(res);
}
static int bfs(String start) {
String end = "12345678x";
Queue<String> q = new LinkedList<>();
Set<String> set = new HashSet<>();
q.add(start);
set.add(start);
int step = 0;
while(!q.isEmpty()) {
int size = q.size();
for (int k = 0; k < size; k++) {
String cur = q.poll();
if (cur.equals(end)) return step;
char[] temp = cur.toCharArray();
// System.out.println(temp);
int idx = cur.indexOf('x');
// System.out.println(idx);
int x = idx / 3, y = idx % 3;
// System.out.println(x + " " + y);
for (int[] dir : dirs) {
int i = x + dir[0], j = y + dir[1];
if (i >= 0 && i < 3 && j >= 0 && j < 3) {
char c = temp[i * 3 + j];
temp[i * 3 + j] = temp[idx];
temp[idx] = c;
String n = new String(temp);
if (!set.contains(n)) {
set.add(n);
q.add(n);
}
c = temp[idx];
temp[idx] = temp[i*3+j] ;
temp[i*3+j] = c;
}
}
}
step++;
}
return -1;
}
}