蓝桥杯 跳蚱蜢 BFS set判重 Java

题目描述

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

如下图所示: 有 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);
	}

}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值