赞
踩
-
-
-
- import java.util.*;
-
- public class Main{
- static String end = "12345678x";
- public static void swap(char[] arr,int x,int y){
- char temp = arr[x];
- arr[x] = arr[y];
- arr[y] = temp;
- }
-
- public static int bfs(String start){
- //key:String 存放12345678x这种格式的字符
- //value:int 存放start - key 这个状态需要多少步
- //最终的map.get(end)就是答案
- Map<String,Integer> map = new HashMap<>();
- //里面放12345678x这种格式的字符
- Queue<String> q = new LinkedList<>();
-
- //开始宽搜
- //先把头节点放入队列
- q.offer(start);
- //初始化头节点
- //根据上面的定义 start -> start所需的步数为0
- map.put(start,0);
-
- //用将字符串转成3 * 3的数组,用偏移量来表示哪些点可以走(可以交换)(可以走到x这个位置)
- int[] dx = {-1,0,1,0}, dy = {0,1,0,-1};
-
- while (!q.isEmpty()){
- //只要队列不空,就把队头拿出来,并把队头可以扩展的点放入
- String t = q.poll();
-
- if (t.equals(end)) return map.get(t);
-
- //然后对t做文章(扩展)
- //t是12345678x格式的字符,要找到x的下标,对应到3 * 3的矩阵,去找可以上下左右扩展的点
- int k = t.indexOf('x');
-
- int x = k / 3;
- int y = k % 3;
-
- for (int i = 0; i < 4; i++) {
- int a = x + dx[i];
- int b = y + dy[i];
- //将满足条件的点(没被用过且再矩阵內部)加入队列,更新map
- if (a >= 0 && b >= 0 && a < 3 && b < 3){
- //将满足条件的点()加入队列,更新map
- //拿到下一个点的状态,看看这个状态是否已经被遍历过了
- char[] arr = t.toCharArray();
- swap(arr,k,a * 3 + b);
- //此时的arr数组就是下一个可以走的点
- //将arr转成字符串
- String str = new String(arr);
- if (map.get(str) == null){
- //该点第一次遍历,更新map里的点并且把它放入队列
- map.put(str,map.get(t) + 1);
- q.offer(str);
- }
- //因为这里操作的是arr数组,并没有操作t,恢复现场可有可无
- }
- }
- }
- return -1;
- }
-
- public static void main(String[] args){
- Scanner sc = new Scanner(System.in);
- String start = "";
- for (int i = 0; i < 9; i++) {
- String s = sc.next();
- start += s;
- }
- System.out.println(bfs(start));
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。