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所需的步数为0map.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];//将满足条件的点(没被用过且再矩阵內部)加入队列,更新mapif (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));}
}