力扣杯 2023 春季战队赛「提取咒语」三重状态 BFS 解法——基于 codeforces-go 仓库的题解与 Go 实现
科学计算【免费下载链接】codeforces-go算法竞赛模板库 by 灵茶山艾府 项目地址https://gitcode.com/GitHub_Trending/co/codeforces-go点击查看免费下载本文以 codeforces-go 仓库中 leetcode/season/2023spring2/c/README.md 的题解笔记为核心系统讲解力扣杯 2023 春季战队赛 T3「提取咒语」的最优解法将「位置 提取进度」编码为三重状态(i, j, k)后做 BFS 最短路搜索。读完本文你将掌握这类「网格移动 顺序收集/提取」题型的通用建模方法并看到该题在仓库内的 Go 模板、测试用例与测试框架的完整配套。一、题目背景网格中按顺序提取咒语本题出自力扣杯 2023 春季个人赛/战队赛题目「提取咒语」仓库对应位置为 leetcode/season/2023spring2/c。题面可概括为给定一个m × n的字符网格matrix每一行是一个字符串以及一个目标字符串mantra咒语初始时玩家位于左上角(0, 0)每一步可以从当前格移动到上、下、左、右相邻的四格之一也可以在当前格原地提取字符前提是当前格字符恰好等于咒语中下一个待提取字符每步花费时间均为 1要求按顺序从mantra[0]到mantra[l-1]收集齐咒语求最少步数若无法完成返回-1。仓库测试文件 c_test.go 中保留了该题在力扣上的题号kjpLFZ数据结构为func extractMantra(a []string, s string) int即传入[]string矩阵每行与咒语字符串返回最少步数。二、核心思路把「提取进度」加入状态转化为三维 BFS2.1 为什么朴素 BFS 不够若只把位置(i, j)当作状态无法区分「当前已经提取到咒语的第几个字符」——到达同一格时已经集齐的字符数不同后续所需步数完全不同。因此必须把提取进度一并纳入状态。2.2 三重状态(i, j, k)的定义继承原题解原题解给出如下状态机这是全文的灵魂状态为(i, j, k)表示当前在格子(i, j)接下来要去提取mantra[k]即前k个字符已经提取完毕0 ≤ k ≤ ll为咒语长度提取转移如果matrix[i][j] mantra[k]则无需移动即可提取该字符状态变为(i, j, k1)移动转移枚举当前格周围四个格子移动到(i, j)提取进度k不变状态变为(i, j, k)初始状态(0, 0, 0)位于起点一个字符都没提取终点k l即所有字符均已提取完毕。在这个状态空间里每一步提取或移动一格都是一条权为 1 的边因此从初始状态到任意(i, j, l)状态的最短路径长度就是答案标准 BFS 即可求解。若 BFS 结束后仍未到达k l返回-1。2.3 剪枝三维 visited 数组状态总数只有m × n × (l1)个每个状态至多入队一次。因此用vis[i][j][k]布尔数组去重即可这也是 BFS 最短路的正确性保证首次访问即最短路后到的同一状态不可能更优。三、Python 3 参考实现原题解代码原 README 中给出的 Python 实现逐层BFS 按层扩展完成上述状态机class Solution: def extractMantra(self, matrix: List[str], mantra: str) - int: m, n len(matrix), len(matrix[0]) q [(0, 0, 0)] # 起点 vis {q[0]} step 1 while q: tmp q q [] for i, j, k in tmp: if matrix[i][j] mantra[k]: # 可以提取 if k len(mantra) - 1: # 下一步就是终点直接返回 return step p (i, j, k 1) if p not in vis: vis.add(p) q.append(p) # 枚举周围四个格子 for x, y in (i 1, j), (i - 1, j), (i, j 1), (i, j - 1): if 0 x m and 0 y n: p (x, y, k) if p not in vis: vis.add(p) q.append(p) step 1 return -1 # 无法到达终点两点细节说明step从 1 开始计数代表「已经付出的行动步数」当某状态在当前位置能够提取mantra的最后一个字符时下一次行动即可到达终点k l因此直接返回当前step采用「层扩展」写法tmp q; q []天然保证同层状态同步处理无需引入距离数组也便于直接返回最小步数。四、Go 实现对齐仓库模板与测试框架仓库中的题解模板文件 c.go 目前保留了函数签名与c_test.go中调用的函数名完全一致package main // https://space.bilibili.com/206214 func extractMantra(a []string, s string) (ans int) { m, n : len(a), len(a[0]) return }按同样的状态机可以补全为如下 Go 实现与 Python 版一一对应供本地验证package main type state struct{ i, j, k int } func extractMantra(a []string, s string) int { m, n : len(a), len(a[0]) // vis[i][j][k]是否访问过状态 (i,j,k)k 最多到 len(s)终点 vis : make([][][]bool, m) for i : range vis { vis[i] make([][]bool, n) for j : range vis[i] { vis[i][j] make([]bool, len(s)1) } } q : []state{{0, 0, 0}} vis[0][0][0] true dirs : [4][2]int{{1, 0}, {-1, 0}, {0, 1}, {0, -1}} step : 1 for len(q) 0 { tmp : q q nil for _, st : range tmp { if a[st.i][st.j] s[st.k] { // 可以提取 if st.k len(s)-1 { // 下一步就是终点 klen(s) return step } ns : state{st.i, st.j, st.k 1} if !vis[ns.i][ns.j][ns.k] { vis[ns.i][ns.j][ns.k] true q append(q, ns) } } // 枚举周围四个格子 for _, d : range dirs { x, y : st.id[0], st.jd[1] if 0 x x m 0 y y n { ns : state{x, y, st.k} if !vis[x][y][ns.k] { vis[x][y][ns.k] true q append(q, ns) } } } } step } return -1 // 无法到达终点 }4.1 仓库测试框架如何驱动本题c_test.go 使用仓库自带的力扣测试工具链func Test_c(t *testing.T) { targetCaseNum : 0 // -1 if err : testutil.RunLeetCodeFuncWithFile(t, extractMantra, c.txt, targetCaseNum); err ! nil { t.Fatal(err) } if err : testutil.RunFuncWithRandomInput(t, extractMantra); err ! nil { t.Fatal(err) } }其中RunLeetCodeFuncWithFile定义在 leetcode/testutil/leetcode.go它按「每入参个数 出参个数行一组」解析c.txt再通过反射调用目标函数并与期望输出比对targetCaseNum 0表示跑全部用例设为-1则只跑最后一组。测试用例文本 c.txt 内容如下[sd,ep] speed 10 [abc,daf,geg] -1第 1 组矩阵[sd,ep]2 行 2 列咒语speed期望输出10即最少 10 步第 2 组矩阵[abc,daf,geg]咒语无法集齐例如目标字符在网格中根本不存在期望输出-1。可在仓库根目录直接运行go test ./leetcode/season/2023spring2/c -run Test_c -v五、复杂度分析沿用原题解的复杂度结论时间复杂度O(mnl)其中m、n分别为matrix的行数和列数l为mantra的长度。状态总数m × n × (l1)每个状态做常数次转移提取 1 次 四方向移动 4 次空间复杂度O(mnl)主要由三维 visited 数组或 Python 版的 set 集合承载BFS 队列在最坏情况下也达到状态总数规模。当l较大时mnl可能不小但本题网格与咒语长度均在可控范围内该复杂度下 BFS 完全可过这也是「以空间换清晰建模」的典型取舍。六、扩展与可迁移的模型从本题可提炼一个通用模式在后续网格类 BFS 题中可直接复用凡是在网格移动之外还带有「顺序进度」「剩余资源」「已携带物品」等一维连续约束的就把该维度加进 BFS 状态使状态空间成为位置维度 × 进度维度的笛卡尔积再用多维 visited 剪枝。例如仓库中大量网格题见 copypasta/graph_grid.go、copypasta/search.go 等通用图与搜索工具以及 copypasta/template/leetcode 下的 LeetCode 模板都遵循「先确定状态、再讨论转移、最后验证终点」的三步法。若遇到状态空间仍过大如mnl接近极限的情形可以进一步考虑 0-1 BFS、双向 BFS 或 A* 等优化手段但在本题约束下并不必要。参考文件索引原题解笔记leetcode/season/2023spring2/c/README.mdGo 模板leetcode/season/2023spring2/c/c.go测试驱动leetcode/season/2023spring2/c/c_test.go测试数据leetcode/season/2023spring2/c/c.txt力扣测试框架leetcode/testutil/leetcode.go赞分享科学计算【免费下载链接】codeforces-go算法竞赛模板库 by 灵茶山艾府 项目地址https://gitcode.com/GitHub_Trending/co/codeforces-go点击查看免费下载相关推荐codeforces-go 力扣杯 2023 春·战队赛题解runeReserve 排序后相邻扫描求最长符文段codeforces go 力扣杯 2023 春·战队赛题解runeReserve 排序后相邻扫描求最长符文段 本篇题解对应 leetcode/season/科学计算力扣 2022 秋季赛个人赛 D 题三开关状态机树形 DP 关闭二叉树全部灯codeforces-go 仓库实战解析力扣 2022 秋季赛个人赛 D 题三开关状态机树形 DP 关闭二叉树全部灯codeforces go 仓库实战解析 本文基于 codeforces go科学计算力扣杯 2023 春·战队赛第四题进化记录字典序最小化递归 子树排序——codeforces-go 题解与源码解析力扣杯 2023 春·战队赛第四题进化记录字典序最小化递归 子树排序——codeforces go 题解与源码解析 本文围绕力扣杯 2023 春·战队科学计算创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Claude Code 是什么?从 CLI Agent 到 MCP 的完整入门指南

Claude Code 是什么?从 CLI Agent 到 MCP 的完整入门指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 19:03:08 阅读更多 →
Claude Code 的 claude-hud 一切换供应商就消失?一文彻底解决

Claude Code 的 claude-hud 一切换供应商就消失?一文彻底解决

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 16:40:57 阅读更多 →
PyCharm 里 Copilot 与 Claude 插件消失?用 TaoToken 统一 Key 排查配置

PyCharm 里 Copilot 与 Claude 插件消失?用 TaoToken 统一 Key 排查配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 16:40:57 阅读更多 →

最新新闻

纯Java手写TopoJSON生成器:从GeoJSON到拓扑压缩的完整实践

纯Java手写TopoJSON生成器:从GeoJSON到拓扑压缩的完整实践

做 WebGIS 的同学这两年应该对 TopoJSON 不陌生,尤其当你需要把全省县级行政区划、全国路网这类动不动几十 MB 的 GeoJSON 塞进浏览器时,TopoJSON 几乎成了绕不开的选项。它的核心价值只有一句话:在拓扑关系上做文章,让共享边界只…

2026/10/10 20:47:31 阅读更多 →
Spring Boot+MyBatis Plus游戏分享网站毕设全流程实战解析

Spring Boot+MyBatis Plus游戏分享网站毕设全流程实战解析

每年的毕业设计季,总能看到一批同学被“选题”折磨得焦头烂额。游戏分享网站这种项目,听起来难度适中、事务清晰,特别适合拿来当计算机专业的毕设项目,但实际动起手来,从技术栈选型到功能模块拆解,再到部署…

2026/10/10 20:47:31 阅读更多 →
给 AI 生成 UI 上“护栏“:json-render 白名单配置从零到生产

给 AI 生成 UI 上“护栏“:json-render 白名单配置从零到生产

给 AI 生成 UI 上"护栏":json-render 白名单配置从零到生产 【免费下载链接】json-render The Generative UI framework 项目地址: https://gitcode.com/GitHub_Trending/js/json-render 2026 年初,Vercel Labs 开源的 json-render 在短…

2026/10/10 20:47:31 阅读更多 →
用NAS把收藏夹文章变成专属播客:搭建指南

用NAS把收藏夹文章变成专属播客:搭建指南

我猜你八成也有这么个毛病:看到一篇好文章先收藏,想着“回头认真读”,结果这个“回头”就是永远。收藏夹里堆了几百篇深度长文,从AI技术、投资分析到历史考据,什么都有,就是没有时间去读。直到有天我在通勤…

2026/10/10 20:47:31 阅读更多 →
把“留痕“当一等公民:金融智能体的审计设计为什么比模型能力更烧钱

把“留痕“当一等公民:金融智能体的审计设计为什么比模型能力更烧钱

把"留痕"当一等公民:金融智能体的审计设计为什么比模型能力更烧钱 【免费下载链接】financial-services 可将 Claude 转变为金融服务专家,适用于投资银行、股票研究等领域。提供核心及专项插件,支持端到端工作流,集成多…

2026/10/10 20:47:31 阅读更多 →
基于Java的校园二手智能交易平台APP开发全攻略

基于Java的校园二手智能交易平台APP开发全攻略

1. 项目到底在做什么:需求与定位拆解每年毕业设计季,“校园二手交易平台”这类题目都是常青树,但今年我带着学生把“基于Java的校园二手智能交易平台APP”完整做成可运行系统时,发现很多人对这个题目的理解还停留在十年前&#xf…

2026/10/10 20:46:30 阅读更多 →

日新闻

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

1. 从“卫星轨道分类”这个标题说起:为什么值得花时间搞懂第一次接触“卫星轨道分类”这个概念,很多人会觉得它离自己很远——不就是天上的星星怎么转吗?但如果你正在做航天任务规划、遥感数据接收、星座设计,甚至只是准备一场航天…

2026/10/10 0:00:39 阅读更多 →
Spring AOP 核心原理与实战:从概念到日志切面落地

Spring AOP 核心原理与实战:从概念到日志切面落地

1. 从一个真实痛点说起:为什么你的代码里到处都是重复逻辑刚入行那会儿,我写过一个用户管理模块,注册、登录、改密码、注销四个接口。每个接口里都塞了几乎一样的日志打印、参数校验、事务开启和提交。当时觉得没什么,能跑就行。直…

2026/10/10 0:00:40 阅读更多 →
Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

简介:这是一套面向计算机相关专业学生与项目实战学习者的Python数据采集与分析可视化完整项目,以Boss直聘岗位数据为对象,适合用作毕业设计、课程设计或期末大作业。资源包共38个文件,约246KB,以13个py源码文件为核心&…

2026/10/10 0:00:40 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 11:14:25 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 1:36:08 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 11:14:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 5:23:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 21:32:20 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 10:38:42 阅读更多 →