析题
Keywords
析题、启发式题解、解题报告、题目分析、代码精讲、逐行讲解
Summary
为竞赛题目生成启发式题解,核心是「教人思考」而非「给答案」。
触发
- 用户要求写「题解」「解题报告」「题目分析」「代码精讲」
- 用户给题面(URL/文件/文本),期望思路解读
- 用户给标程文件,要求逐行讲解
不触发
- 仅搬运/翻译/打包题目 → 搬题姬
- 仅生成测试数据 → 搬题姬
- 说「这题怎么做」但无题面无上下文 → 先确认题面
Strategy
1. 拿题面
| 输入 | 方法 |
|---|---|
| URL | urlgo snapshot(不可用时 WebFetch) |
| 文件 | Read |
| 对话文本 | 直接使用 |
| 标程文件 | Read,融入精讲 |
2. 定深浅
看分值 + 数据范围(数值为参考,非铁律):
| 深度 | 参考分值 | 写法 |
|---|---|---|
| 浅 | ≤ 250 | 一两段说清思路,代码关键行加注。无须逐步推演,无须错误表 |
| 中 | 250~450 | 展示核心思维过程,公式用 LaTeX + 数值例,附 2~3 条常见错误 |
| 深 | ≥ 450 | 暴力 → 撞墙 → 优化 → 数据结构选型,充分展开,代码逐段精讲 |
若分值跨越边界,或数据范围异常大/小,AI 自行判断深度,宁浅勿深。
Human-in-the-Loop:定完深浅后问用户——"本题我判断为 X 难度,您希望浅写还是深写?有没有特定标程要我精讲?"
3. 写(因题制宜,无固定模板)
排列组合自由,但必须覆盖以下六点:
- 直觉入口——读完题的第一反应(哪怕是最笨的暴力)
- 关键转折——什么观察让你找到了正确的路?展示歧路 → 正解的思维跳跃
- 因果链条——(哥哥 2026-08-22 严令)发现了什么 → 因为什么 → 所以用什么算法 → 怎么写的代码,四环贯通,见 4e 铁律
- 代码呈现——贴代码,关键行加注释。不贴裸代码
- 复杂度——时间 + 空间复杂度拆解
- 常见陷阱——容易踩的坑(浅度可省略)
- 样例保真——题面样例原样保留,绝不篡改
六点可自由组合。可先贴代码再解释,也可边推演边贴片段。因题制宜。
推荐布局(今日实战沉淀,成熟好用)——按以下小节组织,尤其适合同中难题:
## X - 标题 题解 ### 题目一句话 —— 一行说清题意 ### 怎么想 —— 思维过程:朴素→卡点→关键观察(见 4d 规律发现路径) ### 关键点 —— 核心洞察,一句话点透 ### 逻辑链 —— Mermaid 居中图(flowchart,见图表规范) ### 复杂度 —— 时间 + 空间 ### 参考代码 —— 见「用户代码处理」,附点评 (### 易错点) —— 中难题必配:UB/边界隐患 + 修正写法该布局是参考框架而非模板——简单题可合并"怎么想/关键点",深难题可拆"怎么想"为多步。核心不变:读者能跟着你的思维走一遍。
若是比赛多题,题与题独立成节,默认合一文件(如 abc471_题解_A-E.typ → PDF),末尾加串讲总结;不散成多个文件,除非用户要求。
产物判定(哥哥 2026-08-23 严令)——判据是「要不要动图」,不是题数:
| 场景 | 产物 | 理由 |
|---|---|---|
| 单题且算法过程要动态可视化(动图) | HTML 单文件(anime.js/cytoscape 动画) | 网页上传,逐帧可播 |
| 多题(一律 typst,不管有无动图需求) | typst → PDF(学术风,静态组图) | 微信群/打印,动图无意义 |
| 单题、但哥哥强调用 typst / 单题无动图需求 | typst → PDF(学术风) | 尊重明确指定 |
- 多题题解一律 typst:不写逐题动画——用多张静态图(组图)表示变化(
#snapshots状态组图 /#booktabs三线表 / Mermaid 式流程图),见templates/example-multi.typ - HTML 仅限「单题 + 需动图」且哥哥未指定 typst
- 哥哥说「用 typst」时,单题也用 typst(无动图,静态组图代替)
- typst 产物统一套
templates/theme-academic.typ(A4 学术风),编译命令typst compile <xxx>.typ <xxx>.pdf - HTML 产物保留原有规范(见交付要求)
详见 steps/02-write.md。
4. 写作心法(析题特色)
以下三点是析题区别于普通题解的关键:
4a. 公式要用数值例解释
不要只扔一行 LaTeX 就跑。数学符号对部分读者是黑话,必须配一个具体数值例子。
不好:concat(x,y) ≡ x + y (mod M)
好: concat(2,1)=21, 21÷2=10余1, 2+1=3÷2=1余1 → 余数相同 ✓
实操规则:每个公式后面紧跟一个「举个例」。例子用小数字,读者能心算。
4b. 展示歧路,而非绕过歧路
遇到需要「关键转折」的题,先写为什么第一反应是错的,再写正确的路。
不好:观察到 BFS 距离奇偶性即可
好: 第一反应 BFS 距离偶→#、奇→.,但全黑格全部输出 #
手动追两步发现全黑格 step1 全白后就再也回不来了
所以需要另一个视角——距离最近白格的距离——补齐盲区
读者需要知道为什么简单的解法不够,才能理解复杂解法的必要性。
4c. 「对面视角」技巧
当问题从某个角度难以直接求解时,主动反问:
反过来呢?从对立面出发呢?
典型案例(今日 ABC460 D):
- 第一 BFS:每个格子到最近
#的距离 → 对.格子有效 - 第二 BFS:每个格子到最近
.的距离 → 对#格子有效 - 两者互补,覆盖全部
在题解中标注这种「换视角」的时刻,帮助读者建立思维灵活性。
4d. 「规律发现路径」(今日实战沉淀)
用户最想看的不是结论,是规律怎么被发现的。标准路径三步,题解里照此展开:
- 手推样例找结构——把小样例在纸上跑一遍,观察变化中的不变量。如 ABC471 C:手推
-11 -4 -1 2的取曲奇过程,发现"已取集合在排序序列里始终是一段连续区间"。 - 追问"为什么必然"——对观察到的结构追问原因,把"现象"升格为"性质"。如:为什么已取集合必然连续?因为最近的未取点只可能是已取区间的左右外侧邻居(内侧已取光,外侧之外更远)。
- 把性质翻译成算法——性质成立,算法自然浮现。连续区间 + 两侧候选 → 双指针两端扩展。
写"怎么想"时务必包含这条路径,不要直接甩性质。读者要知道性质是从哪一步冒出来的。
4e. 因果链条铁律(哥哥 2026-08-22 严令)
写题解必走来龙去脉的因果链:发现了什么 → 因为什么 → 所以用什么算法 → 怎么写的代码。四环缺一不可,不许只堆结论。
发现:手推样例时注意到 X 现象(如:窗口滑出一天后,剩余和只差一个数)
因为:最近 M 天窗口每次只动一格,重复求和的都是同一批数(现象背后的原因)
所以:用滑动窗口——维护窗口和,滑出减、滑进加,O(N) 一趟(原因推出算法)
代码:于是 s += a[i] - a[i-m]*f[i-m] 一行同时完成滑出与尝试加今天(算法落到代码)
叙事模板(怎么写):
- 发现了什么——第一反应/直觉入口,哪怕是笨暴力("读完题我第一反应是每天重扫 M 天,O(NM)")
- 因为什么——这个反应为什么不够?卡在哪?(具体反例或复杂度崩塌)
- 转折观察——手推/换视角发现了什么现象,追问"为什么必然",升格为性质
- 所以用什么算法——性质 → 算法("因为已取集合必然连续,所以候选只有左右两个,所以双指针")
- 怎么写的代码——算法落到代码,关键行标注"这一步就是性质 X 的直接翻译"
禁止:"观察到 XXX,用 YYY 即可"(跳过了因为和所以);"显然/易知"(把因果链藏起来)。因果链是题解的灵魂——读者要能复现你的思维过程,而非背诵你的结论。与 4d 规律发现路径配套:4d 讲规律怎么发现,4e 讲因果怎么贯通。
5. 口吻规范(今日实战沉淀)
- 老师视角 + 活泼诙谐:以讲解者口吻行文("我们"、"这里有个细节"、"注意"),像课堂讲题,不是代码仓库 README。风格基调:活泼诙谐——善用比喻、适度夸张、口语化感叹,让读者读着不困。
- ✅ 诙谐示范:"暴力枚举?那可是 O(n²) 的快乐,n=10^5 时能让你数到天荒地老。""双指针像两个相向而行的侦探,从两端往中间搜,谁小了谁先走。""这题卡了很多人,别慌,我们来拆它的台。"
- ✅ 诙谐示范:"答案藏在'升序'两个字里——题目都给你排好队了,你还傻傻地两两配对所有组合,这不是浪费吗?"
- ❌ 反例:干巴巴报流程"首先初始化,然后循环,最后输出"——读者秒睡。
- ❌ 反例:硬凹梗、玩梗过多盖过内容、用梗时公式/复杂度说不清——诙谐是佐料,不是主菜。
- 诙谐分寸(铁律):①代码、公式、复杂度、数据范围必须精确,玩笑只发生在叙述层;②面向竞赛学生,梗要雅俗共赏(比喻/夸张/口语),不玩烂梗黄梗;③每题开头可来一句俏皮话破冰,正文保持"讲清楚"优先;④样例验证、易错点处可以配吐槽("这里当年坑了半个班"),但修正写法必须严谨。
- 禁"你的代码":引用用户提供的代码时,小节标题用**「参考代码」,配「点评」**(老师评讲:哪里妙、哪里该改)。全文不出现"你的代码/你写的"这类指向性措辞。
- 易错点用"曾踩坑"式:指出隐患时说清"为什么是坑、错在哪、怎么改",给修正代码。
5. 代码风格约定(信奥赛规范)
面向竞赛学生的题解,代码须遵循以下风格。若用户未明确要求风格,默认使用此规范。
变量命名
- 长度不超过 5 字符。如
n, m, k, ans, mx, mn, rt, p, l, r - 根节点用
rt(不用root,不用r——易与"右"混淆) - 计数器用
cnt,临时变量用t
传参原则
- 能用全局变量就全局。前序/中序数组、结果数组等声明为全局。
- 传参越少越好。典型模式:
- 递归只传区间边界,用全局光标遍历另一序列
- 树重建:全局光标
k遍历前序,函数只传中序范围(l, r)
int a[N], b[N]; // a: 前序, b: 中序, 全局 int k; // 前序光标 void dfs(int l, int r) { if (l > r) return; int rt = a[k++]; int p = l; while (b[p] != rt) p++; dfs(l, p - 1); dfs(p + 1, r); cout << rt << ' '; }
格式
- 左大括号另起一行
- 不用
bits/stdc++.h,用具体头文件 - 少用 STL 容器(
vector,stack,queue),优先全局数组模拟 - 能用
string就不用char[]
注释
- 关键行加注,一行注释 5~15 字,不写多行块注释
- 递归调用注释写明区间含义,如
// 左子树:中序[l, p-1] - 不写废话注释(
// 循环、// 赋值)
6. 留空练习模式(按需触发)
仅在用户主动说「留空」「挖空」「填空」或类似要求时启用。 默认不挖空。
思路:代码中挖去 3~5 个关键处(______),答案藏在前文文字描述中,学生细读可寻。
挖空原则:
- 只挖核心逻辑处,不挖语法细节
- ✅ 挖
if (______) return;(递归出口条件) - ✅ 挖
rt = _______;(如何取根) - ✅ 挖
b[p] != ____(比较对象) - ❌ 不挖
int、const、cin >>这类固定写法
- ✅ 挖
- 每段代码 3 空足矣,太多则丧志
- 答案必须在文字中直接出现过(或可通过简单推理得出)
- 开头加一句说明:「下面代码挖去了若干关键处,答案已在前面描述中,仔细读一遍就能填上。」
深浅调整:
- 浅写:挖 2~3 空
- 深写:挖 3~5 空
7. 用户代码处理(今日实战沉淀)
用户提供自己的代码(如 a.cpp~e.cpp)时:
- 逐字摘录主逻辑——直接引用其代码,模板头(
#include/#define/using等)从略但须注明"完整文件见 xxx,模板头从略";代码块与其源文件逐字一致,不得改写、不得"优化"掉他的写法(除非在点评中指出)。 - 一致性校验——生成后对每个代码块与源文件逐字比对(摘录逻辑段),不一致必修正。
- 隐患排查——审视其代码中的未定义行为与边界漏洞(如 erase 后使用失效迭代器、数组负下标越界、整数截断等),在「易错点」小节指出,给修正写法,措辞用"曾踩坑/需修正"而非指责。
- 点评——正确处肯定(如"空串哨兵法,写法干净"),问题处指正,全部老师口吻。
交付要求
产物判定(2026-08-23 哥哥严令):判据是「要不要动图 + 哥哥是否指定」,先判再动手。
| 场景 | 产物 | 模板 | 验证 |
|---|---|---|---|
| 单题 + 需要动态动画 + 哥哥未指定 typst | HTML 单文件 | templates/example.html |
urlgo 开页验证 |
| 多题(一律 typst) | typst → PDF | templates/example-multi.typ + theme-academic.typ |
typst compile 出 PDF |
| 单题、哥哥强调 typst / 单题无动图需求 | typst → PDF | templates/example-multi.typ + theme-academic.typ |
typst compile 出 PDF |
多题题解(typst 版)要点:
- 命名
<比赛>_题解_A-X.typ(同目录放theme-academic.typ或 import 相对路径),编译typst compile <文件> 题解.pdf - 完整模板:
templates/example-full.typ(ABC472 七题完整成品,含全部要素)——直接抄结构 - 每题结构:
#problem-statement(题面+题目一句话)→ 剧情插画 → 怎么想(因果链)→ 关键点(#key-point)→ SVG 多帧图(展示状态变化)→ 样例演示(#booktabs)→ 复杂度 → 参考代码(codly)→ 点评(#review)→ 易错点(#warn) - 多题不用动画——用多帧 SVG 图表示变化(每图 3~4 帧横向排列、帧间箭头,展示动态过程),生成器
templates/gen_figs.py(改数据即可),图存templates/figs/ - 剧情插画:每题在题面与怎么想之间嵌一张 Agnes 生成的教材配图插画(
templates/illu/有样例),风格教材配图+彩色点缀,#align(center, image("xxx.png", width: 55%)) - 代码块用 codly(
#show: code-init),数学用$...$(typst 原生,<=勿写leq) - 末尾串讲
- 产出后
typst compile验证 PDF 生成、页数合理、无 error(warning 可忽略)
typst 语法坑(踩坑沉淀):
- SVG 字体:SVG 内
font-family只写"Noto Serif CJK SC"——写"Libertinus Serif, serif"会让中文回退成隶书(STLiti);SVG 内文字禁斜体(中文无斜体变体,回退隶书) - 表格公式:booktabs 内含公式的 cell 必须用 content 语法
[...](如[$|S-2P_k|$]),写字符串"$...$"不渲染公式 - 数学模式:
$...$内禁中文($sum 分子$报错);代码变量名(dp、par、cross、lca等)用反引号`dp`而非数学;连写变量$O(NM)$报错须$O(N M)$ - 函数参数内:
#strong[...]在#booktabs(...)等函数调用内要去掉#(代码模式)写成strong[...] #在正文要转义\#- 图注用
#captionless[...](theme 已定义,小字灰禁斜体防隶书)
单题 + 动图(HTML 版)要点(HTML 仅限此场景:单题 + 需动图 + 哥哥未指定 typst):
- 格式:HTML 单文件(自足、iframe 友好),命名
<比赛/题目>_题解.html - 结构、CDN、样式必须套用
templates/example.html骨架——内含全部基础 CSS 与脚本 - 每题必含:①题面原文(题目描述/输入输出格式/数据范围/样例输入输出,用
.xt-statement)②思路讲解 ③复杂度 ④参考代码+点评 ⑤样例演示(表格逐步验证) - 中难题(≥250 分)必含:⑥多解法递进(暴力→优化→最优)⑦动态可视化动画(anime.js/cytoscape 步进演示,见下方「动画规范」)
- 代码块用
<pre class="xt-code"><code class="language-cpp">,highlight.js CDN 高亮,带行号(模板 JS 自动拆分.xt-ln,CSS counter 编号,复制不带行号) - 数学用 KaTeX(
$行内,$$行间,auto-render 渲染) - 图表用 Mermaid(
<pre class="mermaid">顶格书写,mermaid.js CDN 渲染,见下方规范) - 有标程必须逐关键行精讲
- 产出后必须验证:urlgo 打开产物截图,确认 Mermaid 图、公式、代码高亮、动画均正常,无 CDN 报错;多题检查分节与串讲完整(详见下方「HTML 产物规范」)
动画规范(仅 HTML 产物、中难题必配)
HTML 产物中,中等难度(≥250 分)及以上的题,思路讲解必须配动态可视化动画——把算法过程用步进动画演给学生看(多题 typst 产物不配动画,用静态组图):
- CDN 库:anime.js
https://cdn.jsdelivr.net/npm/animejs@3.2.2/lib/anime.min.js(defer 引入,模板已含) - 容器:
.xt-viz区块(模板已含样式),内部结构:动画主体(如.xt-viz-array格子阵列)+ 控制条 + 解说行.xt-viz-msg - 控制条四钮必配:▶ 播放 / ⏸ 暂停 / ⏭ 单步 / ⟲ 重置——教学动画必须有步进能力,不能只自动播
- 解说行:每一步显示当前状态文字(如
a[0]=2 + a[4]=15 = 17 > 11 → r--),与动画同步 - 步进数据预计算:先按算法逻辑生成 steps 数组(每步含指针/状态/解说),再渲染——动画是"状态回放",不是实时计算
- 动画类型对照:
| 算法 | 可视化形式 | 参考实现 |
|---|---|---|
| 数组遍历/最值 | 格子扫描高亮 | 仿 B 题改 steps |
| 双指针/二分 | 左右指针移动、命中高亮 | B 题(模板已实现,直接改数据) |
| 排序 | 元素交换/冒泡上浮 | 仿 B 题改 steps |
| BFS/DFS | 节点访问顺序着色 + 队列/栈 | 格子或节点阵列 |
| DP | 表格逐格填充高亮 | 二维格子阵列 |
| 贪心/构造 | 状态逐步变化 | 仿 B 题 |
- 数据小:动画用样例或小规模数据(≤ 8 个元素),格子宽度 48px,数据大了换表格
HTML 产物规范
产物为单文件 HTML,以 iframe 形式嵌入讲义平台(智国学堂 / 01oj 均如此),故必须满足:
- 自足:全部 CSS 内联于
<style>,全部内容内联于正文;不得引用本地相对路径资源(iframe 内相对路径失效) - 命名空间隔离:类名一律
xt-前缀(如xt-wrap、xt-sec、xt-code),避免与宿主平台 CSS 冲突 - CDN 依赖(哥哥选定方案:CDN 实时渲染):
- KaTeX:
https://cdn.jsdelivr.net/npm/katex@0.16.21/dist/katex.min.css+katex.min.js+contrib/auto-render.min.js - highlight.js:
https://cdn.jsdelivr.net/npm/highlight.js@11/styles/github-dark.min.css+https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.11.1/build/highlight.min.js - mermaid:
https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js - anime.js(动画):
https://cdn.jsdelivr.net/npm/animejs@3.2.2/lib/anime.min.js - 脚本全部
defer,初始化逻辑在DOMContentLoaded内(模板已写就,直接复制)
- KaTeX:
- CDN 失败可回退:mermaid 源码以文本留在
<pre>内仍可读;代码无高亮仍可读;公式throwOnError: false不崩页 - 响应式:
.xt-wrapmax-width 860px 居中,代码块overflow-x: auto - 公式防误伤:KaTeX
ignoredTags必须含code/pre,防 C++ 代码中$被误渲染 - Mermaid 源码顶格:
<pre class="mermaid">内第一列即写 flowchart,勿缩进——缩进会污染节点文字;居中由 CSS(.mermaid { text-align:center })保证
组装流程:复制 templates/example.html → 替换题头/小节/代码/图表/公式 → 校对各节 → 本地验证(见上)。
图表规范
禁用手打 ASCII 画图——所有流程图、结构图、步骤图一律用 Mermaid 或内嵌 SVG。
首选:Mermaid
必须使用 Mermaid 的场景:
| 场景 | 图表类型 | 示例 |
|---|---|---|
| 算法主流程 | flowchart TD | 从输入到输出的完整流程 |
| 构造/转换过程 | flowchart LR | A → B → C → D 的步骤链 |
| 思维分支/决策 | flowchart TD | 条件判断、路径选择 |
| 样例验证 | table | 逐行验证(不用 flowchart,太冗长) |
禁止使用的图表:
- ❌ pie chart(渲染效果差,数据不可读)
- ❌ 复杂的 subgraph 嵌套(保持扁平)
- ❌ 超过 8 个节点的单链 flowchart(拆分或用 table)
Mermaid 写法要点(HTML 产物,注意非 md):
<pre class="mermaid">
flowchart LR
A["步骤1: 描述"] --> B["步骤2: 描述"]
B --> C{"判断条件"}
C -->|是| D["结果1"]
C -->|否| E["结果2"]
style A fill:#e3f2fd
style D fill:#c8e6c9
style E fill:#ffcdd2
</pre>
- ⚠️ Mermaid 图整体居中由 CSS 保证(
.mermaid { text-align:center }),无需手动包裹 div <pre class="mermaid">内源码必须顶格书写,第一列即写 flowchart,无缩进(缩进会污染节点文字)- 节点文字用引号包裹,支持
<br/>换行 - 用
style给关键节点着色(起点蓝、终点绿、判断橙、错误红) - 子图(subgraph)仅在逻辑分组明确时使用,否则保持扁平
AVOID
- ❌ 先给最优解再解释——读者不知道你为什么想到它
- ❌ 说「显然」「易知」「不难发现」跳过关键推理
- ❌ 对所有题用同样深度——100 分的题不配 500 字
- ❌ 篡改样例(尤其 AtCoder 比赛禁令期间)
- ❌ 代码不加注释
- ❌ 忘记复杂度分析
- ❌ 套固定模板——因题制宜,每道题有自己的写法
- ❌ 传参贪多——能用全局变量就全局,传参越少越好
- ❌ 注释长篇大论——一行注释 5~15 字,不写块注释包围代码
- ❌ 一股脑堆优化——教学场景先讲朴素版本,学生理解了再提优化
- ❌ 默认留空——除非用户说"留空",否则一律给完整代码
- ❌ 手打 ASCII 画流程图/结构图——一律用 Mermaid 或内嵌 SVG
- ❌ 说"你的代码"——老师口吻,用「参考代码」+「点评」
- ❌ 改写用户代码——逐字摘录其主逻辑,模板头从略并注明;勿擅自"优化"其写法
- ❌ 跳过代码隐患——发现 UB/越界/截断等,必在「易错点」指出并给修正,不装没看见
- ❌ 逻辑链只写文字——中难题逻辑链配 Mermaid 居中图(flowchart),纯文字推导可读性差
