题目描述
本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。
如下图所示: 有 99 只盘子,排成 11 个圆圈。 其中 88 只盘子内装着 88 只蚱蜢,有一个是空盘。 我们把这些蚱蜢顺时针编号为 11 ~ 88。
每只蚱蜢都可以跳到相邻的空盘中, 也可以再用点力,越过一个相邻的蚱蜢跳到空盘中。
请你计算一下,如果要使得蚱蜢们的队形改为按照逆时针排列, 并且保持空盘的位置不变(也就是 1−81−8 换位,2−72−7换位,...),至少要经过多少次跳跃?
运行限制
- 最大运行时间:1s
- 最大运行内存: 128M
最少路径问题需要用到BFS。字符串形式的结点,需要用到set判重
让空盘子去跳其他,跳就是交换(换位)的意思,把环看成线性的。初始值为012345678
目标是087654321。当结点等于目标值时,成功终止。
空盘子(0)可以移动的位置为-2、-1、1、2,使用广度优先搜索,第一次扩展为:
712345608(将0和7交换位置,-2)
812345670(将0和8交换位置,-1)
102345678(将0和1交换位置,1)
210345678(将0和2交换位置,2)
now = (last + dir[i] +9)%9
import java.util.LinkedList;
import java.util.Queue;
import java.util.Set;
import java.util.TreeSet;
public class Main{
static String init = "012345678";//初始
static String target = "087654321";//目标
static int len;//记录长度
static int dir[] = {-2,-1,1,2};//方向
static Queue<String> q = new LinkedList<>();//bfs需要用到的队列
static Set<String> set = new TreeSet<>();//用set去重复
public static void main(String[] args) {
q.add(init);
set.add(init);
bfs();//先将初始值加入队列
}
private static void bfs() {
len = 0;
while(!q.isEmpty()){
int size = q.size();
for(int i =0;i<size;i++){//记录bfs层数,方便计数
String temp = q.poll();//将队列中的第一个赋值给temp并且删除
if(temp.equals(target)){//当前值与目标值相同时,输出层数,成功终止
System.out.println(len);
return;
}
for(int j = 0;j<4;j++){
int last = temp.indexOf('0');//找到字符串中‘0’的位置
int now = (last + dir[j] + 9) % 9;//需要的当前位置
String str = jump(temp,last,now);//交换
if(!set.contains(str)){//判重,如果set中没有该值,则加入队列,加入set
q.add(str);
set.add(str);
}
}
}
len ++;//记录层数
}
}
private static String jump(String temp,int last,int now) {
char[] arr= temp.toCharArray();
char a = arr[last];
arr[last] = arr[now];
arr[now] = a;
return new String(arr);
}
}