蓝桥杯第642题——跳蚱蜢

题目描述

如下图所示: 有 9 只盘子,排成 1 个圆圈。 其中 8 只盘子内装着 8 只蚱蜢,有一个是空盘。 我们把这些蚱蜢顺时针编号为 1 ~ 8。

图片描述

每只蚱蜢都可以跳到相邻的空盘中, 也可以再用点力,越过一个相邻的蚱蜢跳到空盘中。

请你计算一下,如果要使得蚱蜢们的队形改为按照逆时针排列, 并且保持空盘的位置不变(也就是 1−8 换位,2−7换位,...),至少要经过多少次跳跃?

解题思路

这道题是典型的BFS相关例题,可以练习BFS判重,以及双向广搜的具体方式。

我们从蚱蜢跳跃去考虑并不方便,因为我们每次都有很多只蚱蜢可以进行跳跃,因此我们可以转换思维,考虑到只有一个空盘子,所以第一次跳跃的情况是必定有一只蚱蜢跳到空盘子里;而下一次操作也是同样的情况。

所以我们考虑有哪些蚱蜢可以跳到空盘子上,进一步思考,就是空盘子可以与哪些蚱蜢交换位置,很明显,如图所示,0号空盘可以与2、1、8、7号蚱蜢交换位置,这就为我们提供了搜索路径的灵感;同时,我们是要找到最少的跳跃次数,也就是最短路径,因此我们考虑广度优先搜索。

因为这题不像迷宫,有一个明显的特点,也就是0和2交换的结果——可以由0和1交换,0和2交换,1再和2交换获得。那么这就会导致很多重复,所以后来变换的结果如果与前面已经获取过的结果有重叠,就应当剪枝不再计算,这里我们考虑使用HashSet结构和HashMap结构进行去重。

单点BFS

我们使用一个ArrayDeque构成的队列实现BFS,队列中每个节点的内容是当前的字符串s和得到它所走过的步数step,另外使用一个HashSet来记录搜索过的字符串,很明显先进来的字符串所带来的step数值是最小的,判重过后只需要忽略后续来的相同字符串即可。

以下是常规bfs判重的解题代码:

import java.io.*;
import java.util.*;public class Main {static String S1 = "012345678";static String S2 = "087654321";static int num = 0;     // 计算队列的操作次数,用于与双向广搜对比public static void main(String[] args) throws IOException {Set<String> set = new HashSet<>();ArrayDeque<Pair> qu = new ArrayDeque<>();qu.addLast(new Pair(S1, 0));set.add(S1);while (!qu.isEmpty()) {Pair temp = qu.removeFirst();if (temp.s.equals(S2)) {System.out.println(temp.step);System.out.println(num);break;}// 使用index记录当前字符串中0所在的位置int index = 0;for (int i = 0; i < 9; i++) {if (temp.s.charAt(i) == '0') {index = i;break;}}for (int i = index - 2; i <= index + 2; i++) {num++;     // num的每次自增意味着计算的执行次数增加// 使用取余技巧获取将要进行交换的下标int k = (i + 9) % 9;// 5次循环中忽略实际没有交换的情况if (k == index) {continue;}char[] ss = temp.s.toCharArray();char t = ss[k]; ss[k] = ss[index]; ss[index] = t;if (set.add(String.copyValueOf(ss))) {qu.addLast(new Pair(String.copyValueOf(ss), temp.step + 1));}}}}
}class Pair {String s;int step;public Pair(String s, int step) {this.s = s;this.step = step;}
}

 结果输出中,第一个数值是题目所要求的答案,第二个值代表着该算法的运行次数。

20
1814315
第一种思路的局限性

在考虑单点bfs找最短路径的情况,我们可以想象原点是一颗由上至下的4叉树,那么题目的答案20,意味着我们要向下分出20层才能找到答案,树会不断往底部扩展,越是向下的层数,所需要计算的节点就越是多,如果我们没有去重,想象一个完整的20层4叉树,它是非常巨大的。

那么我们可以考虑另外一种情况,现在我们明确的知道目标结果的字符串,那么我们可以不可以根据最终状态再反向生成一颗树呢?

如果从上至下以及从下至上同时开始广搜,那么我们所需要生成的四叉树就从一个20层的树变成了两个10层的树,同学们可以自行想象,这对时间的节省又是相当巨大的。

双向广搜

在上述单点BFS的基础上,我们进行升级为双向广搜,每次对队列的一次BFS操作都根据队列长度较短的进行选择执行,第一次遇到相同字符串的时候,两个层数加起来就是我们的答案。

我们需要将第一种方式的一个Set修改为两个独立的HashMap,记录字符串出现的同时,也要对应记录其出现的层数,方便我们对答案进行输出。

import java.io.*;
import java.util.*;public class Main {static String S1 = "012345678";static String S2 = "087654321";static int times = 0;static int ans = 0;public static void main(String[] args) throws IOException {HashMap<String, Integer> map1 = new HashMap<>();HashMap<String, Integer> map2 = new HashMap<>();ArrayDeque<Pair> qu1 = new ArrayDeque<>();ArrayDeque<Pair> qu2 = new ArrayDeque<>();qu1.addLast(new Pair(S1, 0));map1.put(S1, 0);qu2.addLast(new Pair(S2, 0));map2.put(S2, 0);while (!qu1.isEmpty() && !qu2.isEmpty()) {if (qu1.size() < qu2.size()) {extend(qu1, map1, map2);} else {extend(qu2, map2, map1);}if (ans != 0) {System.out.println(ans);System.out.println(times);break;}}}// 注意该方法中的qu是当前操作的队列// map对应的是qu的HashMap// 而map1是另外一个队列的HashMappublic static void extend(ArrayDeque<Pair> qu, HashMap<String, Integer> map, HashMap<String, Integer> map1) {Pair temp = qu.removeFirst();if (map1.containsKey(temp.s)) {ans = temp.step + map1.get(temp.s);return;}int index = -1;for (int i = 0; i < temp.s.length(); i++) {if (temp.s.charAt(i) == '0') {index = i;break;}}for (int i = index - 2; i <= index + 2; i++) {times++;int k = (i + temp.s.length()) % temp.s.length();if (k == index) {continue;}char[] arr = temp.s.toCharArray();char ch = arr[index]; arr[index] = arr[k]; arr[k] = ch;String news = String.copyValueOf(arr);if (!map.containsKey(news)) {map.put(news, temp.step + 1);qu.addLast(new Pair(news, temp.step + 1));}}}
}class Pair {String s;int step;public Pair(String s, int step) {this.s = s;this.step = step;}
}
20
133510

通过两种方法的输出对比我们可以看出,对队列的操作次数由180万降低到了13万,这也是双向广搜的厉害之处。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/756175.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据库学习记录(一)基础语法与单表查询

基础sql语句分类 DDL操作&#xff08;图形化界面&#xff09; 用来定义数据库对象的&#xff0c;例如创建数据库&#xff0c;创建表单 数据库操作 表操作 DML操作&#xff08;掌握&#xff09; 1、insert为添加语句&#xff0c;该语句功能是添加相关数据到表结构中 下面为添…

学习笔记 | 微信小程序项目day04

今日学习内容 热门推荐下转页面 热门推荐下转页面 1、定义类型 import type { PageResult, GoodsItem } from ./global/** 热门推荐 */ export type HotResult {/** id信息 */id: string/** 活动图片 */bannerPicture: string/** 活动标题 */title: string/** 子类选项 */…

开源的OCR工具基本使用:PaddleOCR/Tesseract/CnOCR

前言 因项目需要&#xff0c;调研了一下目前市面上一些开源的OCR工具&#xff0c;支持本地部署&#xff0c;非调用API&#xff0c;主要有PaddleOCR/CnOCR/chinese_lite OCR/EasyOCR/Tesseract/chineseocr/mmocr这几款产品。 本文主要尝试了EasyOCR/CnOCR/Tesseract/PaddleOCR这…

【开源】SpringBoot框架开发不良邮件过滤系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 系统用户模块2.2 收件箱模块2.3 发件箱模块2.4 垃圾箱模块2.5 回收站模块2.6 邮箱过滤设置模块 三、实体类设计3.1 系统用户3.2 邮件3.3 其他实体 四、系统展示五、核心代码5.1 查询收件箱档案5.2 查询回收站档案5.3 新…

C语言 数组

文章目录 1.一维数组2.二维数组3.冒泡排序4.一维函数的数组名5.二维数组的数组名 1.一维数组 语法形式&#xff1a;type_t arr_name [const_n] 数组是一组相同类型元素的集合 type_t是指数组的元素类型 arr_name是指数组的名称 const_n是一个常量表达式&#xff0c;用来指定数…

mongoDB7.0.6版安装与使用(最新版踩坑记录)

这里写自定义目录标题 0.前言1.MongoDB下载与安装2.启动服务及验证3.命令行访问4.navicat访问5.停止服务 0.前言 本文总结了最近版mongoDB下载安装的过程及简单的应用&#xff0c;整个过程不涉及修改配置文件&#xff0c;甚至不用设置用户名密码也不用登录认证&#xff0c;在进…

HarmonyOS NEXT应用开发—投票动效实现案例

介绍 本示例介绍使用绘制组件中的Polygon组件配合使用显式动画以及borderRadius实现投票pk组件。 效果预览图 使用说明 加载完成后会有一个胶囊块被切割成两个等大的图形来作为投票的两个选项&#xff0c;中间由PK两字分隔开点击左边选项&#xff0c;两个图形会随着选择人数…

Java城管智慧执法管理系统源码带APP

目录 一、系统概述 二、系统开发环境 三、功能模块 四、应用价值 1、提升案件办理效率 2、提升监管效能 3、提升行政执法水平 4、推进行政执法创新 一、系统概述 智慧城管系统是一个基于现代信息技术手段的综合管理平台&#xff0c;旨在通过强化信息获取自动化、监督管…

官宣!眉州东坡终生认养大熊猫“星星”

2024年03月19日,眉州东坡终生认养大熊猫“星星”签约仪式暨第八届有机川熊猫竹笋节在北京和重庆同时举行。眉州东坡董事长王刚先生、重庆动物园副处长殷毓中先生等嘉宾在重庆共同出席了此次认养仪式,重庆动物园向眉州东坡授予大熊猫终生认养证书,宣布星星正式加入眉州东坡大家庭…

Game of Nodes 16进8

KNIME 还可以用成这样? 是不是有点过分了。 Tableau, PowerBI 同学请绕行&#xff0c;我们讨论的不是同一个东西... 由于 Game of Nodes 没有公开题目&#xff0c;且各个小组赛的题目也是不一样的&#xff0c;在这里我们只能通过拼接图来猜想小组赛题目了。 有的解决方案我甚至…

Android源码阅读 SharedPreferences - 1

目录 前言 正文 SharedPreferences.java PreferenceManager.java ContextImpl.java 前言 由于笔者目前水平限制&#xff0c;表达能力有限&#xff0c;尽请见谅。 SharedPreferences提供了一种轻量级的数据存储方式&#xff0c;允许保存和获取简单的键值对。它适用于保存少…

中霖教育:一级建造师和一级造价师通过率高吗?

在建筑工业领域&#xff0c;一级建造师和一级造价工程师考试都是比较热门的考试&#xff0c;每年参加的人数都非常多&#xff0c;如果只备考一个的话&#xff0c;2024年选择哪项考试更为合适? 一建和一造的平均通过率均未超过10%&#xff0c;两者难度相近&#xff1a; 1. 一…

力扣刷题---岛屿问题--c++

DFS&#xff1a;深度优先遍历&#xff1a;深度优先遍历是一种优先走到底、无路可走再回头的遍历方式 我们所熟悉的 DFS&#xff08;深度优先搜索&#xff09;问题通常是在树或者图结构上进行的。而我们今天要讨论的 DFS 问题&#xff0c;是在一种「网格」结构中进行的。岛屿问题…

源码部署LAMP架构

LAMP 文章目录 LAMP1. lamp简介2. web服务器工作流程2.1 cgi与fastcgi2.2 httpd与php结合的方式2.3 web工作流程 3. LAMP平台构建3.1 安装httpd3.2 安装mysql3.3 安装php3.4 验证 1. lamp简介 有了前面学习的知识的铺垫&#xff0c;今天可以来学习下第一个常用的web架构了。 …

【基于HTML5的网页设计及应用】——动态添加下拉菜单

&#x1f383;个人专栏&#xff1a; &#x1f42c; 算法设计与分析&#xff1a;算法设计与分析_IT闫的博客-CSDN博客 &#x1f433;Java基础&#xff1a;Java基础_IT闫的博客-CSDN博客 &#x1f40b;c语言&#xff1a;c语言_IT闫的博客-CSDN博客 &#x1f41f;MySQL&#xff1a…

什么是增强型SSL证书?购买一张需要多少钱?

增强型SSL证书是一种提供更高级别安全验证与用户信任度的网络安全工具&#xff0c;也被称为EV证书。相较于DV&#xff08;域名验证&#xff09;和OV&#xff08;组织验证&#xff09;证书&#xff0c;它通过严格的身份核实流程确保网站所有者的合法性和真实性。 首先&#xff0…

【C++】string 类---字符判断与大小写转换(超详细解析!)

目录 一、string 类的介绍 二、字符大小写转换与判断常用函数 &#x1f4a6; 字符大小写判断 ① isalpha() ② isalnum() ③ isdigit() ④ islower() ⑤ isupper() &#x1f4a6; 字符大小写转换 ① tolower() ✨方法一&#xff1a; ✨方法二&#xff1a; ② toupper() ✨方…

【MySQL】MySQL视图

文章目录 一、视图的基本使用1.创建视图2.修改了视图&#xff0c;对基表数据有影响3.修改了基表&#xff0c;对视图有影响4.删除视图 二、视图规则和限制 一、视图的基本使用 视图是一个虚拟表&#xff0c;其内容由查询定义。同真实的表一样&#xff0c;视图包含一系列带有名称…

【springboot】@SpringBootApplication 加载原理解析

从何处放入 AutoConfigurationImportSelector.selectImports AbstractApplicationContext.refresh AbstractApplicationContext.invokeBeanFactoryPostProcessors PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors 此处一个关键信息 只有BeanDefinition…

Html Open with Live Server 报错windows找不到文件

输入setting.json 填入你的浏览器路径 即可