
简介《算法竞赛入门经典第二版》例题答案资源包由刘汝佳所著经典教材配套整理面向正在备战ACM/ICPC等程序设计竞赛的初学者与进阶选手。压缩包内共224个文件其中以191个C源程序为主体覆盖书中各章节核心例题的完整实现另有12个测试输入文件、10个答案输出文件及11个Markdown说明文档便于对照验证与理解代码思路。资源整体仅208KB轻量便携。已有2003人学习下载。知识点涵盖基础排序与搜索、动态规划、图论最短路径与最小生成树、字符串KMP匹配、组合数学与数论、常用数据结构、贪心策略以及递归分治等竞赛高频考点。通过研读这些目标代码与配套数据读者能更直观地掌握算法设计和编码技巧提升实战解题能力。1. 例题答案不是用来抄的先搞清楚这本书在教什么搜“算法竞赛入门经典第二版例题答案”的人多半已经买了书翻到某道例题卡在“为什么我的代码跑不出书上的结果”或者“书上这段代码为什么要这么写”。这本书确实是国内算法竞赛入门最经典的一本第二版的例题代码以 C 为主覆盖枚举、递归、回溯、图论、动态规划等核心专题绝大多数例题都有完整的解法代码。但很多人第一次打开配套代码时面对的不是“看不懂”而是“跑不起来”“结果不对”“代码和书上不一样”。这篇文章不打算把所有例题答案贴一遍——那既违反版权也违背这本书的设计意图。我按自己当初带着这本书入门、后来给几个同学答疑的经验把“如何正确拿到并验证例题答案”“如何用答案反推思路”“踩过哪些坑”整条链路讲清楚。目标是让你拿到任何一道例题都能在本地跑通、看懂、改成自己的风格并迁移到题库里的同类题。版本以第二版为基准代码基于 C11O2 编译选项下验证。2. 抓题号、对章节、分清楚“例题”和“习题”是两套东西2.1 这本书的章节骨架和例题分布特征第二版全书大致分为三块语言基础第一章到第四章、竞赛专题第五章到第九章含 STL、数据结构、暴力求解、动态规划等、实战与陷阱第十章左右开始覆盖数学专题和高级技巧。多数例题集中在中间章节每一道题都有编号比如“例题 2-1”这类格式。这个编号不是你随便在某个 OJ 上搜“2-1”就能搜到的它的真实含义是“原题出自某个在线评测系统”书的附录或配套资源里通常有题源映射表。我建议你拿到书之后先不要急着买任何电子版答案包。第一步是把自己手头这本第二章到第五章的例题编号全部列出来然后去原书配套的代码仓库或作者维护的博客文章里按编号查。这一步花不了二十分钟但能帮你建立“题号—专题—OJ 源题”的映射。后面写代码、查讨论、看别人题解都靠这张映射表。2.2 例题答案的四种来源与甄别方法常见来源无非四种原书作者配套发布的源码包、第三方整理仓库里的答案、各种技术社区的单题讨论帖、以及 OJ 上其他用户提交的 AC 代码。权威性从高到低排序源码包优于整理仓库整理仓库优于社区帖社区帖优于随手复制来的提交记录。一个小提示网上很多“例题答案”整理包里面其实混了练习题Exercise的代码甚至还有读者自己写的版本不一定和原书解法一致。我见过有人照着某整理包敲了一下午发现代码调用的头文件和书上对不上最后才知道那是另一本书的答案。所以判断一个答案是否可信第一眼要看代码顶部的注释块有没有标注例题编号和题源 OJ第二眼看有没有包含多组输入数据的循环处理——算法竞赛题的代码几乎都要处理到 EOF。提示凡是只贴了核心函数、没有完整输入输出处理的“答案”要么是片段要么是伪代码要么是讲解用代码。这类内容参考思路可以直接提交必挂。3. 本地环境先弄对Win 和 Linux 下跑例题代码的三件套3.1 编译器选型和命令行编译参数这本书的代码有几个硬性特征大量使用 STL、部分例题用了 C11 特性比如 auto、unordered_map少数代码假设了 GNU 扩展。所以本地环境第一原则不要用老旧的 VC6 或 Dev-C 5.0 自带的远古编译器至少用 GCC 7 以上的版本。Windows 下我一般推荐直接装 MinGW-w64 的 GCC装完在命令行里验证g --version g -stdc11 -O2 -Wall -o test test.cpp第一条命令看编译器版本第二条编译。-stdc11是这本书例题的基本盘不写这个参数有些例题会因为隐式类型转换规则不同产生编译错误-O2是竞赛常用优化等级绝大多数 OJ 也是开 O2 评测的-Wall用来开警告能帮你提前发现数组越界、变量未初始化这类问题。Linux / macOS 下系统自带的 g 或 clang 也可以用但 macOS 的 clang 对bits/stdc.h支持不全。这本书的部分例题代码会 include 这个万能头在 Linux 的 GCC 下没问题macOS 下可能要拆成具体头文件。如果你卡在“代码一模一样但就是编译不过”先查是不是这个头文件的锅。3.2 用输入重定向摆脱手工敲数据的折磨例题代码无论从哪个 OJ 来读输入的方式都是标准输入流。你在本地跑的时候如果每次都在黑窗口里手动敲测试数据两三组就烦了。正确做法是把测试数据存成文本文件用输入重定向喂进去./test data1.in ./test data1.in my.out第一条命令把 data1.in 的内容作为标准输入喂给程序结果打印到屏幕第二条把结果写入 my.out。这样做的额外好处是你可以用 diff 命令快速对比自己的输出和标准答案输出而不是盯着屏幕一行行看。Windows 的命令提示符和 PowerShell 也支持和重定向用法完全一样。如果你用的是 VS Code 的集成终端记得把终端切换到 cmd 或 PowerShell 再执行别在“运行”对话框里写带重定向的命令——那是跑不起来的。我自己的习惯是每个例题建一个文件夹里面放a.cpp、data.in、data.out标准答案三个文件跑完生成my.out最后用diff或fc对比。这个习惯后面做多组数据回归时非常好用。4. 例题答案验证闭环从自己写、对比到提交的完整步骤4.1 以经典例题为例先动手写一版再看答案直接看答案是学习效率最低的方式。我的做法是读完题后哪怕思路不完整也先憋一版代码出来。比如这本书第二章有道很经典的题UVA 1003n1 问题你自己写出来的第一版可能长这样#include cstdio int cycle_length(int n) { int cnt 1; while (n ! 1) { if (n % 2 1) { n 3 * n 1; } else { n n / 2; } cnt; } return cnt; } int main() { int a, b; while (scanf(%d%d, a, b) 2) { int max_len 0; int low a b ? a : b; int high a b ? a : b; for (int i low; i high; i) { int len cycle_length(i); if (len max_len) max_len len; } printf(%d %d %d\n, a, b, max_len); } return 0; }这段代码逻辑上对了但如果不做缓存遇到1 1000000这种大范围数据会跑得很慢——原因很简单cycle_length对每个数字从头算一遍重复计算了大量中间结果。书上的参考答案通常会加一个记忆化数组把算过的n的循环长度存起来。你先写出上面的版本再对照答案就能一眼看出差距在哪不是语法问题是算法思维问题。参数说明a和b是输入区间的两个端点题目没说谁大谁小所以代码里用low和high统一处理scanf返回值判断是竞赛代码的标准写法防止输入结束时报错。如果你发现自己写的版本没有处理a b的情况恭喜你踩中了这道题最经典的坑。4.2 用批处理脚本做多组数据回归跑通一组样例不代表代码正确OJ 上的测试数据远比例题附带的样例刁钻。我常用的验证方式是自己构造多组边界数据然后写一个脚本批量回归。Windows 下用批处理脚本echo off for %%f in (data\*.in) do ( echo Running %%f a.exe %%f tmp.out fc /W tmp.out data\%%~nf.out nul if errorlevel 1 ( echo Failed: %%f ) else ( echo Passed: %%f ) ) del tmp.out这个脚本遍历data目录下所有.in文件逐个运行a.exe把结果和对应的.out标准答案做忽略空白字符的对比。fc /W里的/W参数很关键它忽略行尾空格和连续空格的差异——因为 OJ 评测一般也是忽略行末空白的。Linux / macOS 下用 bash 脚本代替思路完全一致。这类脚本我一般在一个例题调试通过之后才写因为前期代码经常崩写脚本反而浪费时间。当你发现自己开始频繁改动代码并且改了这组数据挂那组数据时就该上回归了。4.3 和参考答案对比时重点看三个地方如果你已经写出一版能跑的代码打开参考答案不要逐行读。先看三个位置第一输入处理循环的写法——是while (scanf(...) N)还是while (cin x)这决定了代码能扛住多少组数据第二关键变量有没有用long long——这本书的例题里大量存在 int 溢出陷阱答案里用long long的位置往往对应着题目数据的隐藏边界第三核心算法的复杂度——答案用的是递归、DP 还是贪心和你的解法差了几个数量级。这三个位置对完了你的收获比逐行读代码大得多。如果你的解法和答案在整体复杂度上差一个级别但样例全过那说明你对题目的理解还停留在“能跑”阶段没到“能过”阶段。这时候强行背答案没有任何意义应该回看题目里的数据范围提示想想为什么你的做法在最坏情况下会超时。5. 例题答案使用避坑指南五个翻车现场复盘5.1 样例输出是错的大概率是题面理解错了网上流传的部分例题答案代码运行后输出的结果和书上印的样例输出不一致。初学者看到这个第一反应是“答案错了”但更常见的原因是书上的样例输出经过重新格式化题源 OJ 的原始输出可能多个空格、少个换行而网上搬家的人直接复制的 OJ 代码。遇到这种情况不要急着改代码。先把题目的完整英文题面找出来逐句看输出格式要求到底是“两个数之间一个空格”还是“每行末尾不能有空格”。这类因输出格式导致的“不一致”本质上是你的代码和 OJ 的 Special Judge 之间的约定问题不是逻辑错误。5.2 代码在本地跑得好好的提交上去超时典型场景你从某答案包拖下来一份代码本地样例秒出交到 OJ 上直接 TLE。原因是这类代码往往是在 O2 优化下写的依赖编译器的自动优化但不同的 OJ 对编译选项有微调。更隐蔽的问题是代码里有大量endl刷新输出缓冲——竞赛里输出几十万行时endl比\n慢一个数量级。解决方法是把std::endl全部替换成\n并在main开头加一行std::ios::sync_with_stdio(false);这行代码关闭 C 流和 C 标准 IO 的同步让cin/cout不再每次读写都做额外检查。如果你的代码用的是printf/scanf不需要加这行但也不能混着用——混用cin和scanf在开了同步关闭之后会导致输入顺序错乱这是我见过最隐蔽的玄学 bug。5.3 数组开小了答案代码的数组大小不能照抄有些例题答案的全局数组长度是按“当前用例最大数据”开的比如int a[1005]看起来很有余量。但原书作者在代码里开这个大小是因为题面当时的数据范围就是这样。后来 OJ 更新了测试数据或者你拿同一道题去另一个 OJ 提交数据范围翻了一倍——数组就越界了。正确做法是读题面里的数据范围上限然后在这个基础上至少加 5 到 10 的余量。如果题面写“N ≤ 10^5”数组就开100005而不是100000。很多算法题会藏着“N1”“N2”这种越一位的边界数据数组开满上限必挂。5.4 参考答案里有勘误对不上时先查勘误表第二版出版后有过几次勘误某些例题的代码在早期印次里存在笔误——比如变量名写错、循环边界差一。这类问题在技术社区里经常有人提但如果你拿的是第三方整理包可能没有同步更新。判断方法看代码里有没有明显的“写了但没用”的变量或者循环条件里出现与题面矛盾的数字。一条简单经验如果答案代码里出现了你没有学过的某个库函数或某种语法先查它的含义再判断是不是笔误不要用“反正作者是大牛代码一定对”来麻醉自己。5.5 打开答案包发现是 .pdf 或图片识别 OCR 和手敲的差异网上流传的一些“例题答案”是扫描版 PDF 或手敲文本。这类资源最大的坑是 OCR 识别错误——l和1不分、0和O混淆、全角标点和半角标点混用。你把这种代码直接编译报错信息可能非常诡异比如“stray \303 in program”这就是全角字符混入代码的典型症状。遇到这种情况不要逐行修——太浪费时间。直接把代码里的全角符号替换成半角替换完再编译sed -i s//,/g; s//(/g; s//)/g a.cpp如果替换完还报错放弃这个答案版本去 OJ 上找 AC 提交记录里的代码或者回原书配套资源里下干净版。血泪经验在错误资源上纠错的时间永远是白费的。6. 从例题答案到独立 AC把对照变成能力的迁移练习你把这本书的例题答案都跑通了之后真正的瓶颈不是“看不懂答案”而是“换了题就不会”。我自己的习惯做法是“三遍法”专门解决这个问题。第一遍独立写写完对照答案标记出自己完全没想到的关键转换比如“这道题为什么要排序”。第二遍隔一天只看自己写的代码和题面注释不看答案重新实现一遍——目标是让代码风格统一而不是照抄答案。第三遍去原题所在的 OJ 找同类题应用例题里的算法变形解决只看题面不求助于任何人。这个流程每道例题大概花两小时比刷十遍答案有效得多。另一个值得做的练习是把例题改成变体。比如原题求最大值你就问自己“如果求最小值代码要改哪一行”原题是单组输入你就改成多组输入到 EOF。这些变体练习能帮你把答案里的算法真正消化成自己的武器。最后说一个个人的教训我在学第三章枚举专题时偷懒直接背了几个例题代码结果做课后习题时碰到一道题表面看起来完全不像例题我愣是没想到可以用枚举加哈希去做——直到看了习题讨论帖才反应过来。从那以后我再也不背答案而是每次看完题先写十分钟思路草稿写不出来才去翻答案。希望帮到你。本文还有配套的精品资源点击获取