当前位置: 首页 > article >正文

bfs-最小步数问题

最小步长模型

  • 特征:

    主要是解决权值为1且状态为字符串类型的最短路问题,实质上是有向图的最短路问题,可以简化为bfs求最短路问题。

  • 代表题目:

    • acwing 845 八数码问题:

      八数码题中由于每次交换的状态是由x进行上下左右移动,采用直接对x的位置进行四个方向枚举,每次求出来x的位置,需要将原字符串的位置转换为 3 * 3 矩阵中的坐标,在四个方向上进行交换x的坐标,每次记录当前状态到起点状态的步数 + 1即可,细节见代码,本题最重要的是学会字符串与二维矩阵之间的坐标转换。

      import java.util.*;public class Main {// 定义四个移动方向:上、下、左、右static int[][] dirs = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};// 获取字符串中 'x' 的索引public static int get(String t) {for (int i = 0; i < t.length(); i++) {if (t.charAt(i) == 'x') {return i;}}return -1; // 理论上不会到达}// 交换字符串 t 中索引 k 和 j 的字符,返回新字符串public static String swap(String t, int k, int j) {char[] arr = t.toCharArray();char temp = arr[k];arr[k] = arr[j];arr[j] = temp;return new String(arr);}// BFS 求解从 start 到 end 的最小移动次数public static int bfs(String start, String end) {// 距离映射:记录每个状态的步数Map<String, Integer> dist = new HashMap<>();// 队列:存储待探索的状态Queue<String> q = new LinkedList<>();q.offer(start);dist.put(start, 0);while (!q.isEmpty()) {String t = q.poll();// 如果当前状态是目标状态,返回步数if (t.equals(end)) {return dist.get(t);}// 找到 'x' 的索引int k = get(t);// 计算 'x' 在 3x3 网格中的坐标int x = k / 3, y = k % 3;// 尝试四个方向移动for (int[] dir : dirs) {int nx = x + dir[0];int ny = y + dir[1];// 检查新坐标是否越界if (nx < 0 || nx >= 3 || ny < 0 || ny >= 3) {continue;}// 计算新位置的索引int newIdx = nx * 3 + ny;// 生成新状态String next = swap(t, k, newIdx);// 如果新状态未访问过,加入队列if (!dist.containsKey(next)) {dist.put(next, dist.get(t) + 1);q.offer(next);}}}// 无法到达目标状态return -1;}public static void main(String[] args) {Scanner sc = new Scanner(System.in);String start = "";for(int i = 0; i < 9; i++) start += sc.next();String end = "12345678x";int res = bfs(start, end);System.out.println(res);}
      }
      

  • 题目2:acwing 1107 魔版 温馨提示代码又臭又长 hhh

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

思路很简单,初始状态和结束状态都已知,要求解最小步数和字典序最小的操作序列,也就是在上个题目的基础上,在bfs的时候要记录当前层的状态是由上一层的哪个状态,通过哪种方式进行转换得到的,所以需要记录路径,根据分析可知,需要用一个哈希表存储,key为当前状态,value需要涵盖上一个状态(String)和操作(char) ,所以这里的map类型为<String, PII>,具体见代码。记录完毕这个路径以后,要获得正序的操作数,需要遍历存储的pre,然后再倒序输出即可,思路不难,代码很长。。

import java.util.*;public class Main {static Map<String, Integer> dist = new HashMap<>(); // 记录当前状态距离初始状态的步数static Map<String,PII> pre = new HashMap<>(); // 存储当前状态由那个状态的哪个操作进行转移过来static char[][] g = new char[2][4];// 将字符串转换为二维矩阵存储public static void set(String t) {for(int i = 0; i < 4; i++) g[0][i] = t.charAt(i);for(int i = 0; i < 4; i++) g[1][i] = t.charAt(7 - i);}// 将二维矩阵转换为字符串public static String get() {String res = "";for(int i = 0; i < 4; i++) res += g[0][i];for(int i = 0; i < 4; i++) res += g[1][3 - i];return res;}// 操作A 交换上下两行public static String moveA(String t) {set(t);char[] temp = new char[4];for(int i = 0; i < 4; i++) {temp[i] = g[0][i];g[0][i] = g[1][i];g[1][i] = temp[i];}return get();}// 操作B 将最右边的一列插入到最左边;public static String moveB(String t) {set(t);char a = g[0][3];char b = g[1][3];for(int i = 3; i >= 1; i--) {g[0][i] = g[0][i - 1];g[1][i] = g[1][i - 1];}g[0][0] = a;g[1][0] = b;return get();}// 操作C 魔板中央对的4个数作顺时针旋转。public static String moveC(String t) {set(t);char a = g[0][1];char b = g[0][2];char c = g[1][1];char d = g[1][2];g[0][1] = c;g[0][2] = a;g[1][1] = d;g[1][2] = b;return get();}public static int bfs(String start, String end) {if(start.equals(end)) return 0;Queue<String> q = new LinkedList<>();q.offer(start);dist.put(start, 0);//  bfs遍历框架while(!q.isEmpty()){String t = q.poll();// 三种操作String[] m = new String[3];m[0] = moveA(t);m[1] = moveB(t);m[2] = moveC(t);for(int i = 0; i < 3; i++) {if(dist.containsKey(m[i])) continue; // 当前的状态被遍历过了 dist.put(m[i], dist.get(t) + 1);// 存储下一个状态由哪个状态+操作进行转移if(pre.containsKey(m[i])) continue;pre.put(m[i], new PII((char) ('A' + i), t));q.offer(m[i]);if(m[i].equals(end)) return dist.get(end);}}return -1;}public static void main(String[] args) {Scanner sc = new Scanner(System.in);String start = "12345678";String end = "";for(int i = 0; i < 8; i++) {end += sc.nextInt();}int step = bfs(start, end);System.out.println(step);// 遍历统计途中的最优解方案String res = "";String ans = end;while(!ans.equals(start)) {res += pre.get(ans).opera;ans = pre.get(ans).str;}for(int i = res.length() - 1; i >= 0; i--) System.out.print(res.charAt(i));}
}class PII {char opera; //  操作 String str; // 状态public PII(char opera, String str) {this.opera = opera;this.str = str;}
}

  • 题目3: leetcode 752 打开转盘锁

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

本题的思路跟上面两题类似,不同点在于多了一个限制条件: deadends,也就是说在bfs的时候如果新得到的状态存在与deadends,则不会继续更新,也就是不会将当前的状态与初始状态连接;此外,每次操作相当于是对四位字符中的一位进行+1/-1操作,因为转盘是圆的,这里需要 + 10 % 10 的操作。

class Solution {static Set<String> lock = new HashSet<>();public static int bfs(String start, String end) {Queue<String> q = new LinkedList<>();Map<String, Integer> dist = new HashMap<>();q.offer(start);dist.put(start, 0);while(!q.isEmpty()) {String t = q.poll();if(t.equals(end)) return dist.get(t);StringBuilder sb = new StringBuilder();for(int i = 0; i < 4; i++) {String s1 = t.substring(0, i);String s2 = t.substring(i + 1, 4);for(int j = -1; j <= 1; j += 2) {int c = (t.charAt(i) - '0' + j + 10) % 10 ;String newStr = s1 + c + s2;if(lock.contains(newStr)) continue;if(dist.containsKey(newStr)) continue;dist.put(newStr, dist.get(t) + 1);q.offer(newStr);}}}return -1;}public int openLock(String[] deadends, String target) {lock.clear();String start = "0000";// 特判起点等于终点if(start.equals(target)) return 0;// 特判起点为不可走for(int i = 0; i < deadends.length; i++) {String t = deadends[i];lock.add(t);}if(lock.contains(start)) return -1;int ans = bfs(start, target);return ans;}
}

相关文章:

bfs-最小步数问题

最小步长模型 特征&#xff1a; 主要是解决权值为1且状态为字符串类型的最短路问题&#xff0c;实质上是有向图的最短路问题&#xff0c;可以简化为bfs求最短路问题。 代表题目&#xff1a; acwing 845 八数码问题&#xff1a; 八数码题中由于每次交换的状态是由x进行上下左右…...

sqlalchemy库详细使用

SQLAlchemy 是 Python 中最强大、最受欢迎的 ORM&#xff08;对象关系映射&#xff09;库&#xff0c;它允许你使用 Python 对象来操作数据库&#xff0c;而不需要直接编写 SQL 语句。同时&#xff0c;它也提供了对底层 SQL 的完全控制能力&#xff0c;适用于从简单脚本到大型企…...

java----------->代理模式

目录 什么是代理模式&#xff1f; 为什么会有代理模式&#xff1f; 怎么写代理模式&#xff1f; 实现代理模式总共需要三步&#xff1a; 什么是代理模式&#xff1f; 代理模式&#xff1a;给目标对象提供一个代理对象&#xff0c;并且由代理对象控制目标对象的引用 代理就是…...

ET ProcessInnerSender类(实体) 分析

ProcessInnerSender 作用是进程内部发送Actor消息 字段 TIMEOUT_TIME 超时时间RpcId 用来累加requestCallback 存储RPC的回调事件list 用来获取MessageQueue中的Actor消息 方法 Awake 初始化在MessageQueue中注册待处理的消息队列Destroy 移除在MessageQueue中的消息队列U…...

Untiy基础学习(十四)核心系统—物理系统之碰撞检测代码篇 刚体,碰撞体,材质

目录 一、碰撞器&#xff08;Collider&#xff09;与触发器&#xff08;Trigger&#xff09; 二、碰撞检测条件 三、碰撞事件与触发器事件&#xff0c;可以理解为特殊的生命周期函数。 四、讲讲如何选择 ​编辑 五、总结 一、碰撞/触发事件函数对照表 二、Collider 与 …...

SAP学习笔记 - 开发08 - Eclipse连接到 BTP Cockpit实例

有关BTP&#xff0c;之前学了一点儿&#xff0c;今天继续学习。 SAP学习笔记 - 开发02 - BTP实操流程&#xff08;账号注册&#xff0c;BTP控制台&#xff0c;BTP集成开发环境搭建&#xff09;_sap btp开发-CSDN博客 如何在Eclipse中连接BTP Cockpit开发环境实例。 1&#xf…...

如何用Redis实现分布式锁?RedLock算法的核心思想?Redisson的看门狗机制原理?

一、Redis分布式锁基础实现 public class RedisDistributedLock {private JedisPool jedisPool;private String lockKey;private String clientId;private int expireTime 30; // 默认30秒public boolean tryLock() {try (Jedis jedis jedisPool.getResource()) {// NX表示不…...

Java项目层级介绍 java 层级 层次

java 层级 层次 实体层 控制器层 数据连接层 Service : 业务处理类 Repository &#xff1a;数据库访问类 Java项目层级介绍 https://blog.csdn.net/m0_67574906/article/details/145811846 在Java项目中&#xff0c;层级结构&#xff08;Layered Architecture&#xf…...

Git的安装和配置(idea中配置Git)

一、Git的下载和安装 前提条件&#xff1a;IntelliJ IDEA 版本是2023.3 &#xff0c;那么配置 Git 时推荐使用 Git 2.40.x 或更高版本 下载地址&#xff1a;CNPM Binaries Mirror 操作&#xff1a;打开链接 → 滚动到页面底部 → 选择2.40.x或更高版本的 .exe 文件&#xf…...

【2025版】Spring Boot面试题

文章目录 1. Spring, Spring MVC, SpringBoot是什么关系&#xff1f;2. 谈一谈对Spring IoC的理解3. Component 和 Bean 的区别&#xff1f;4. Autowired 和 Resource 的区别&#xff1f;5. 注入Bean的方法有哪些&#xff1f;6. 为什么Spring 官方推荐构造函数注入&#xff1f;…...

火山引擎实时音视频 高代码跑通日志

实时音视频 SDK 概览--实时音视频-火山引擎 什么是实时音视频 火山引擎实时音视频&#xff08;Volcengine Real Time Communication&#xff0c;veRTC&#xff09;提供全球范围内高可靠、高并发、低延时的实时音视频通信能力&#xff0c;实现多种类型的实时交流和互动。 通…...

atoi函数,sprintf函数,memcmp函数,strchar函数的具体原型,功能,返回值;以及使用方法

以下是这四个C语言标准库函数的详细说明&#xff1a; 1. atoi() - 字符串转整数 **原型**&#xff1a; int atoi(const char *str); **功能**&#xff1a; 将字符串参数str转换为整数&#xff08;int类型&#xff09;。函数会跳过前面的空白字符&#xff08;如空格、制表符&am…...

C++学习之打车软件git版本控制

目录 01 3-git的简介 02 4-git的下载和提交代码 03 5-git添加一个新文件 04 5-删除一个文件 05 6-git的批量添加和提交文件 06 7-git重命名文件名 07 8-git解决代码冲突 08 9-git的分支的概念 09 10-创建项目代码仓库 10 1-git提交代码复习 01 3-git的简介 1 --------…...

基于 PostgreSQL 的 ABP vNext + ShardingCore 分库分表实战

&#x1f680; 基于 PostgreSQL 的 ABP vNext ShardingCore 分库分表实战 &#x1f4d1; 目录 &#x1f680; 基于 PostgreSQL 的 ABP vNext ShardingCore 分库分表实战✨ 背景介绍&#x1f9f1; 技术选型&#x1f6e0;️ 环境准备✅ Docker Compose&#xff08;多库 & 读…...

jenkins 启动报错

java.lang.UnsatisfiedLinkError: /opt/application/jdk-17.0.11/lib/libfontmanager.so: libfreetype.so.6: cannot open shared object file: No such file or directory。 解决方案&#xff1a; yum install freetype-devel 安装完成之后重启jenkins。...

C++ 套接字函数详细介绍

目录 头文件1. 套接字创建与配置2. 绑定地址与端口3. 连接建立4. 数据传输5. 套接字选项6. 地址转换7. 套接字关闭8. 其他实用函数 C 套接字函数详细介绍 套接字(Socket)是网络通信的基本端点&#xff0c;C中通常使用BSD套接字API进行网络编程。以下是主要的套接字相关函数及其…...

【合新通信】无人机天线拉远RFOF(射频光纤传输)解决方案

无人机天线拉远RFOF方案通过光纤替代传统射频电缆&#xff0c;实现无人机与地面控制站之间的高保真、低损耗信号传输&#xff0c;尤其适用于高频段&#xff08;如毫米波&#xff09;、远距离或复杂电磁环境下的无人机作业场景。 核心应用场景 军事侦察与电子战 隐蔽部署&…...

程序设计语言----软考中级软件设计师(自用学习笔记)

目录 1、解释器和编译器 2、程序的三种控制结构 3、程序中的数据必须具有类型 4、编译、解释程序翻译阶段 5、符号表 6、编译过程 7、上下文无关文法 8、前、中、后缀表达式 9、前、后缀表达式计算 10、语法树中、后序遍历 11、脚本语言和动态语言 12、语法分析方法…...

火山RTC 7 获得远端裸数据

一、获得远端裸数据 1、获得h264数据 1&#xff09;、远端编码后视频数据监测器 /*** locale zh* type callback* region 视频管理* brief 远端编码后视频数据监测器<br>* 注意&#xff1a;回调函数是在 SDK 内部线程&#xff08;非 UI 线程&#xff09;同步抛出来的&a…...

通过SMTP协议实现Linux邮件发送配置指南

一、环境准备与基础配置 1. SMTP服务开通&#xff08;以qq邮箱为例&#xff09; 登录qq邮箱网页端&#xff0c;进入「设置」-「POP3/SMTP/IMAP」 开启「SMTP服务」并获取16位授权码&#xff08;替代邮箱密码使用&#xff09; 记录关键参数&#xff1a; SMTP服务器地址&#…...

若依框架页面

1.页面地址 若依管理系统 2.账号和密码 管理员 账号admin 密码admin123 运维 账号yuwei 密码123456 自己搭建的地址方便大家学习&#xff0c;不要攻击哦&#xff0c;谢谢啊...

44、私有程序集与共享程序集有什么区别?

私有程序集&#xff08;Private Assembly&#xff09;与共享程序集&#xff08;Shared Assembly&#xff09;是.NET框架中程序集部署的两种不同方式&#xff0c;它们在部署位置、版本控制、访问权限等方面存在显著差异&#xff0c;以下是对二者的详细比较&#xff1a; 1. 部署…...

【Java面试题】——this 和 super 的区别

&#x1f381;个人主页&#xff1a;User_芊芊君子 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 &#x1f50d;系列专栏&#xff1a;【Java】内容概括 【前言】 在Java的世界里&#xff0c;this和 super是两个非常重要且容易混淆的关键字。无论是在日常…...

记录 QT 在liunx 下 QFileDialog 类调用问题 ()Linux下QFileDialog没反应)

1. 2025.05.14 踩坑记录 因为QT 在 liunx 文件系统不同导致的 Windows &#xff1a; QString filePath QFileDialog::getOpenFileName(nullptr, "选择文件", ".", "文本文件 (*.txt);所有文件 (*.*)"); 没问题 liunx 下 打不开&#xff…...

CentOS 7 内核升级指南:解决兼容性问题并提升性能

点击上方“程序猿技术大咖”&#xff0c;关注并选择“设为星标” 回复“加群”获取入群讨论资格&#xff01; CentOS 7 默认搭载的 3.10.x 版本内核虽然稳定&#xff0c;但随着硬件和软件技术的快速发展&#xff0c;可能面临以下问题&#xff1a; 硬件兼容性不足&#xff1a;新…...

【前端】:单 HTML 去除 Word 批注

在现代办公中&#xff0c;.docx 文件常用于文档编辑&#xff0c;但其中的批注&#xff08;注释&#xff09;有时需要在分享或归档前被去除。本文将从原理出发&#xff0c;深入剖析如何在纯前端环境下实现对 .docx 文件注释的移除&#xff0c;并提供完整的实现源码。最后&#x…...

解决 PicGo 上传 GitHub图床及Marp中Github图片编译常见难题指南

[目录] 0.行文概述 1.PicGo图片上传失败 2.*关于在Vscode中Marp图片的编译问题* 3.总结与启示行文概述 写作本文的动机是本人看到了Awesome Marp&#xff0c;发现使用 Markdown \texttt{Markdown} Markdown做PPT若加持一些 CSS , JavaScript \texttt{CSS},\texttt{JavaScript} …...

软考 系统架构设计师系列知识点之杂项集萃(59)

接前一篇文章&#xff1a;软考 系统架构设计师系列知识点之杂项集萃&#xff08;58&#xff09; 第96题 假设关系模式R(U, F)&#xff0c;属性集U{A, B, C}&#xff0c;函数依赖集F{A->B, B->C}。若将其分解为p{R1(U1, F1), R2(U2, F2)&#xff0c;其中U1{A, B}, U2{A, …...

python使用matplotlib画图

【README】 plot画图有两种方法&#xff1a;包括 plt.plot(), ax.plot()-画多个子图 &#xff0c;其中ax表示某个坐标轴; 【1】画单个图 import matplotlib # 避免兼容性问题&#xff1a;明确指定 matplotlib 使用兼容的后端&#xff0c;TkAgg 或 Agg matplotlib.use(TkAgg) …...

鸿蒙OSUniApp 开发实时聊天页面的最佳实践与实现#三方框架 #Uniapp

使用 UniApp 开发实时聊天页面的最佳实践与实现 在移动应用开发领域&#xff0c;实时聊天功能已经成为许多应用不可或缺的组成部分。本文将深入探讨如何使用 UniApp 框架开发一个功能完善的实时聊天页面&#xff0c;从布局设计到核心逻辑实现&#xff0c;带领大家一步步打造专…...