在线评测基础题答案:输入输出、模拟、枚举、排序与二分易错点全梳理 简介面向ACM算法初学者与POJ刷题者整理的题解代码合集覆盖北大POJ早期编号及若干经典基础题适合课程作业、在线判题练习和赛前热身时对照参考。压缩包共157个文件以156个cpp源码为主另含1个txt文件整体仅59KB体量轻便便于按题号检索、编译与本地调试。已有2653人学习下载说明其在基础算法训练场景中具有一定参考价值。读者可从中查看不同题目的C实现方式理解输入输出组织、边界条件处理和常见算法套路并借助可运行代码复盘自己的WA或TLE原因源码短小也适合作为模板改写与刷题节奏安排的辅助材料。1. 基础题单不是背答案先把在线评测基础题答案的得分结构看明白在线评测基础题答案这份资料真正值钱的地方不是把每道题的输出抄一遍而是把“读题—建模—边界—提交”这条链路练成条件反射。某高校在线评测基础题单里的题量不算大题型却覆盖输入输出、模拟、枚举、排序查找、二分、递推等笔试高频模块。机试评分只看用例答案对但格式错、边界漏、复杂度爆都是零分。适合两类人一类准备算法笔试和面试手撕另一类刷题总在“样例过、提交挂”上翻车。拿分顺序建议先保输入输出和模拟再攻枚举与排序最后补二分和递推每题必须自己写一遍、调一遍、造三组边界再把答案里的思路对照一遍。基础题单的区分度不在偏题而在谁少丢冤枉分。2. 输入输出与模拟基础题单里最容易先丢分的两块2.1 输入输出格式多组数据、终止条件、空格与换行基础题单的第一道门槛不是算法而是输入输出。很多题看着像“求和”“统计”“打印图形”实际考的是你能不能识别多组数据、读到什么条件停、每组之间要不要空行、行末能不能多空格。在线评测基础题答案里最容易被忽略的往往就是这些格式细节。笔试和面试手撕也类似面试官给一组样例你写出来的函数能不能处理空输入、单元素、重复元素直接决定他信不信你写过工程代码。这类题通常这么答先判断输入是单组还是多组多组看终止条件是读到文件结束、读到 0、还是先给组数输出看是否要求每组空行、是否要求行末无空格。不要一上来写核心逻辑先把输入输出骨架写稳。下面这段是多组求和的骨架适用于“读到结束”的题型。#include bits/stdc.h using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); long long a, b; // while(cin a b) 既完成读取也判断输入流是否还有数据 while (cin a b) { cout a b \n; } return 0; }逻辑说明while (cin a b)是这类题的核心它等价于“还有两个数可读就继续”。参数说明a、b用long long是为了防止两数相加溢出ios::sync_with_stdio(false)和cin.tie(nullptr)用来减少输入输出开销题量大时差别明显。这里输出用\n而不是endl是为了避免频繁刷新缓冲区。真正提交前要检查如果题目要求“每组输出后空一行”就在循环里补空行如果要求“最后一组不空行”就得用计数器控制不能无脑统一处理。再看一种常见变体先给组数T再处理T组。这种题错在把T当成数据读进核心逻辑或者每组结束没清空状态。答法是先读T外层循环while (T--)每组内部重新初始化数组、计数器、标记变量。多组数据题最怕“上一组的脏状态带到下一组”尤其是全局数组和bool标记。面试手撕时也一样函数内部不要依赖上一次调用的残留变量。提示输入输出题先写三组自测最小输入、最大边界、格式最刁钻的输入。样例只覆盖正常路径边界才是失分点。2.2 模拟题按规则推进别把状态写丢模拟题在基础题单里占比很高常见形态是日期累加、开关灯、排队报数、矩阵填数、简单状态机。它们不考高深算法考的是你能不能把规则翻译成变量再按顺序推进。在线评测基础题答案里模拟题的答案往往不长但自己写容易在“边界那一天”“第 0 步”“循环该先加还是后加”上翻车。面试官看模拟题重点也不是你会不会背而是你能不能把状态说清楚。这类题通常这么答先列出状态变量比如当前日期、当前方向、当前人数、当前累计值再写推进规则明确“先判断还是先更新”最后处理终止条件。不要一边写循环一边改规则先把一回合的推进写成固定顺序。以日期累加为例给定起始日期和天数k求k天后的日期。下面是一个可复现的骨架。#include bits/stdc.h using namespace std; int mdays[13] {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; bool isLeap(int y) { // 闰年规则能被4整除且不能被100整除或能被400整除 return (y % 4 0 y % 100 ! 0) || (y % 400 0); } void addDays(int y, int m, int d, int k) { while (k-- 0) { int limit mdays[m]; if (m 2 isLeap(y)) limit 29; d; if (d limit) { d 1; m; if (m 12) { m 1; y; } } } } int main() { int y, m, d, k; cin y m d k; addDays(y, m, d, k); cout y m d \n; return 0; }逻辑说明mdays存平年每月天数isLeap判断闰年addDays每次只推进一天跨月、跨年都在循环里处理。参数说明k是偏移天数y、m、d用引用传入函数直接改原值如果题目要求多组数据就把main里的读取改成循环并注意每组重新读入。易错点在“先加d再判断越界”如果先判断d limit再处理遇到跨月当天就会差一天。模拟题的调试方法很土但有效把k设成 1、28、29、30、31、365 分别跑答案对不上就能定位到哪条规则写反了。2.3 题单演练两道基础题的答题顺序第一道按“多组数据 条件筛选”练。题目大意是多次给出一组整数要求统计满足某条件的个数条件可能涉及正负、奇偶、区间。答题顺序先写while读入再写计数器再写条件判断最后输出。面试官如果追问“如果数据量到 10 万组怎么办”答法不是炫技而是说明输入输出已经加速、每组只扫一遍、空间只开常数级。基础题单里这类题看着简单实际考的是你会不会把“每组重置计数器”写进循环内部。第二道按“矩阵模拟”练。题目大意是按顺时针或蛇形顺序填数再按行输出。答题顺序先定方向数组再定边界判断再定“什么时候转向”。常见错法是四个方向写死但转向条件漏了已填标记导致原地打转。答法是用visited标记或边界收缩每填一个数就检查下一步是否越界或已填。代码不必长关键是把“下一步能不能走”单独写成一个判断别把转向逻辑塞在四个分支里。这两道题的价值不在答案而在答题动作先输入输出再状态变量再推进规则最后边界自测。基础题单刷到后面二分、枚举、递推都会反复用到这套动作。3. 枚举与暴力优化从“能过样例”到“能过用例”3.1 枚举题的三层优化范围、顺序、剪枝枚举是基础题单里最像“送分题”的一类也是最容易超时的一类。在线评测基础题答案里枚举题的答案通常很短但直接照抄容易忽略一个事实同样三层循环范围写错、顺序写反、剪枝漏掉提交结果就从通过变成超时。笔试里枚举题常以“求满足条件的组合数”“统计三元组”“模拟选择过程”出现面试官更在意你能不能说出为什么这样枚举不重不漏。这类题通常这么答第一层定枚举范围能缩就缩第二层定枚举顺序保证不重复第三层定剪枝条件能在进入下一层前排除就提前排除。不要一上来写满循环再在里层if里过滤很多无效分支本可以在外层就砍掉。以百钱买百鸡类问题为例公鸡 5 钱一只母鸡 3 钱一只小鸡 1 钱三只100 钱买 100 只求所有组合。直接三层循环能写但范围可以大幅缩小。#include bits/stdc.h using namespace std; int main() { // x: 公鸡数量最多 20 只y: 母鸡数量最多 33 只 for (int x 0; x 20; x) { for (int y 0; y 33; y) { int z 100 - x - y; // 总数固定为 100z 不必再枚举 if (z 0) continue; // 小鸡数量不能为负 if (z % 3 ! 0) continue; // 小鸡 1 钱 3 只必须被 3 整除 if (5 * x 3 * y z / 3 100) { cout x y z \n; } } } return 0; }逻辑说明总数固定为 100所以z可以由100 - x - y直接算出省掉一层循环z % 3保证钱数计算不出现小数。参数说明x的上界 20 来自100 / 5y的上界 33 来自100 / 3这两个上界不是背出来的是按单价推出来的。剪枝放在进入钱数判断之前能少算很多无效组合。面试时如果被问“还能不能优化”可以答把z用总数约束消掉一层再用整除条件提前过滤复杂度从三层降到两层。3.2 题单演练暴力枚举如何从超时写到通过题目大意给一个长度为n的数组统计满足a[i] a[j] a[k] target的三元组个数n在几百到几千之间。最直接的三层循环是O(n^3)小数据能过大数据必超时。答题顺序先写暴力版确认题意再看能不能排序后双指针最后处理重复元素。面试官最想听的是“我先用暴力确定边界再换枚举对象”不是一上来就背双指针模板。暴力版的答法要写清楚外层i从 0 到n-1中层j从i1到n-1内层k从j1到n-1这样保证不重复。超时后不要慌先看数据范围如果n是 100 以内三层循环可能刚好如果n是 1000就要换思路。常见优化是排序后固定一个数另外两个数用双指针从两端收复杂度降到O(n^2)。这里不贴完整双指针代码重点是答题时把“为什么可以排序”“为什么双指针不会漏解”说清楚排序后和太大就右指针左移和太小就左指针右移等于目标时同时移动并跳过重复值。3.3 面试变体把枚举讲成搜索面试里很少直接说“你写个三重循环”更常见的是“设计一个方案把所有可能情况列出来”。这时枚举要讲成搜索状态是什么、选择是什么、终止条件是什么、怎么去重。基础题单里的枚举题如果只会写循环换到面试场景就容易卡壳。答法是先用一句话定义状态比如“当前考虑到第几个物品已选集合是什么”再说“每一层做选或不选”最后补“用排序或标记去重”。面试官听到这里会认为你既能写基础题也能把思路迁移到回溯和搜索。这类题的易错点不在代码而在边界空集算不算一种情况、重复元素要不要去重、结果按什么顺序输出。基础题单的答案通常只给一组输出但笔试可能要求按字典序。答题时先问清楚输出要求再决定枚举顺序。枚举顺序一旦确定就不要在里层随便打乱否则去重逻辑会崩。4. 排序查找与二分基础题单里的“看起来会写起来错”4.1 排序题不是调用 sort 就完比较器、稳定性、输出顺序排序题在基础题单里出现频率很高常见形态是成绩排序、结构体排序、多关键字排序、按规则重排。在线评测基础题答案里排序代码往往只有几行但自己写容易在比较器上翻车该降序写成升序、相等时没处理第二关键字、输出顺序和题目要求反了。面试手撕排序时面试官不一定让你手写快排但一定会看你能不能说清比较规则。这类题通常这么答先定排序对象是单个值还是结构体再定主关键字和次关键字最后定相等时是否要求稳定。如果题目要求“成绩相同按输入顺序”就不能用不稳定的重排方式或者要在结构体里存原始下标。下面是一个结构体排序骨架。#include bits/stdc.h using namespace std; struct Node { int id; int score; }; int main() { int n; cin n; vectorNode v(n); for (int i 0; i n; i) { cin v[i].id v[i].score; } sort(v.begin(), v.end(), [](const Node a, const Node b) { if (a.score ! b.score) return a.score b.score; // 成绩降序 return a.id b.id; // 成绩相同按编号升序 }); for (auto x : v) { cout x.id x.score \n; } return 0; }逻辑说明比较器先比score分数不同时降序分数相同时比id保证顺序确定。参数说明id可以换成原始输入下标用来实现“成绩相同按输入顺序”score如果可能很大用long long。比较器必须满足严格弱序不要写否则相等元素可能让排序行为未定义。提交前检查输出要求是输出编号还是输出整行是每行一个还是空格分隔。4.2 二分模板边界写错整题白给二分是基础题单里最容易“看着会、写就错”的模块。常见题型有两类一类是在有序数组里找第一个大于等于x的位置另一类是二分答案比如最小化最大值、最大化最小值。在线评测基础题答案里二分代码短但边界条件一错就死循环或漏解。面试官问二分最想听的是“你的区间定义是什么、循环结束时 l 和 r 代表什么”。这类题通常这么答先明确区间是左闭右开还是闭区间再写循环条件最后写返回l还是r。不要混用两套模板。下面是最常用的左闭右开写法找第一个大于等于x的下标。#include bits/stdc.h using namespace std; int lowerBound(const vectorint a, int x) { int l 0, r (int)a.size(); // 区间 [l, r) while (l r) { int mid l (r - l) / 2; // 防止 l r 溢出 if (a[mid] x) { r mid; // 答案在左半区mid 可能是答案 } else { l mid 1; // mid 不满足答案在右半区 } } return l; // l 是第一个 x 的位置可能等于 a.size() }逻辑说明区间定义为[l, r)循环结束时l rl就是第一个满足a[mid] x的位置。参数说明a必须有序x是目标值返回a.size()表示所有元素都小于x。易错点是mid用(l r) / 2在大范围下可能溢出写成l (r - l) / 2更稳。另一个易错点是r mid还是r mid - 1取决于你的区间定义千万别两套混着写。4.3 题单演练二分答案的答题顺序题目大意把n根绳子切成k段等长绳子求每段最大长度保留两位小数。答题顺序先确定答案范围左端 0右端最大绳长再写判断函数给定长度L统计能切出多少段最后二分L。这类题面试官会追问精度循环 100 次够不够、最后输出左端还是右端。答法是循环固定次数避免浮点比较死循环输出时按题目要求保留小数别用cout默认格式。整数二分答案的套路类似先写check(mid)再决定满足时收缩哪边。常见错误是check里用了没初始化的变量或者多组数据没清空。基础题单里这类题的价值在于练“先写判断函数再写二分框架”而不是背模板。判断函数写对了二分只是壳判断函数写错模板再熟也过不了。5. 易错点五类常见失分题及纠正5.1 输入输出类失分样例过、提交挂错在哪看到样例只有一组数据就写死单组读取题目实际是多组或者要求读到 0 结束。为什么错基础题单的样例往往只展示格式不展示终止条件题干里的“多组”“EOF”“以 0 结束”没被当成考点。怎么答对读题时先把输入输出规则圈出来写代码前用注释标清“单组/多组/组数/终止值”多组题每组结束重置计数器。提交前自测三组一组正常、一组最小、一组终止边界。错在哪行末多空格、每组之间少空行、最后一组多空行。为什么错在线评测按字符比对格式错就是错和算法对不对无关。怎么答对输出用统一格式需要空格分隔时控制“第一个元素前不加空格”需要空行时用组号判断不要无脑每组都加。5.2 数组与边界类失分差一错误最要命错在哪循环写i n访问a[n]越界或者二分区间写成闭区间却按开区间收缩。为什么错基础题单的边界用例专门打这种差一错误样例数据小越界不一定崩提交到大数据就挂。怎么答对先定区间语义再写循环条件数组下标从 0 开始时遍历写i n二分题把“区间是[l, r]还是[l, r)”写在注释里返回前检查空数组和单元素。错在哪多组数据共用全局数组上一组标记没清空。为什么错局部变量每组重新创建全局数组不会自动归零第二组开始结果就污染。怎么答对每组开头memset或重新赋值如果数组很大记录本组用到的位置再清不要全量清零导致超时。5.3 整数溢出类失分int 不够却看不出来错在哪两数相加、成绩累加、方案数统计用int结果超过范围变成负数。为什么错基础题单里数据范围常写在题干角落样例数值小看不出溢出。怎么答对看到累加、乘法、组合数先估上界超过 2×10^9 就用long long输出前检查中间变量类型不要只改最后结果。面试手撕时主动说一句“这里用 long long 防止溢出”面试官会认为你有边界意识。5.4 二分与循环类失分死循环和漏解错在哪while (l r)里更新l mid或r mid区间没有缩小程序死循环。为什么错二分模板混用左闭右开和闭区间两套写法拼在一起。怎么答对固定一套模板写之前注释区间mid用l (r - l) / 2满足条件时收缩到mid不满足时收缩到mid 1或mid - 1保证每次区间变短。错在哪二分答案的check函数写错导致满足条件的方向反了。为什么错只背二分壳没想清楚“长度越大段数越少”这类单调关系。怎么答对先用小数据手算check(mid)的返回值再决定收缩方向最后输出左端还是右端按题目问“最大”还是“最小”确定。5.5 模拟与枚举类失分规则顺序写反错在哪模拟题先判断越界再更新导致跨月当天差一天枚举题先过滤再枚举导致漏掉合法组合。为什么错把“判断”和“更新”的顺序当成小事实际状态机题顺序就是逻辑。怎么答对模拟题把一回合拆成“读状态—判断—更新—处理进位”按固定顺序写枚举题先保证范围完整再剪枝剪枝条件必须能证明不会漏解。自测时专门造跨边界数据比如 28 号加 1 天、最后一天加 1 天。6. 考场拆题基础题单里最值得押的五种答题动作6.1 先写骨架再填逻辑拿到题先别急着写核心算法先把输入输出骨架写出来单组还是多组、输出几行、有没有空行。骨架稳了后面填逻辑才不会因为格式返工。基础题单里很多“不会做”其实是“读错输入”。我习惯在草稿上写三行输入格式、输出格式、数据范围再开始敲代码。6.2 每题造三组边界样例只能证明你理解了正常路径边界才能证明你理解了题目。三组边界可以固定为最小规模、最大规模、最容易差一的规模。排序题造重复元素二分题造空区间和单元素模拟题造跨月跨年。自测时不要只看答案要看中间变量有没有越界。6.3 提交前检查清单检查项看什么常见翻车输入单组/多组/终止条件样例一组题目多组输出空格、换行、空行、小数位行末多空格、最后一组多空行类型累加、乘法、方案数int 溢出边界空输入、单元素、最大规模下标越界、死循环状态多组数据是否清空上一组标记污染下一组这张表不花哨但每次提交前走一遍能挡掉大量冤枉分。面试手撕时也可以口头走一遍面试官听到“我先检查空输入和重复元素”就知道你不是只会背模板。6.4 押题思路基础题单反复考的五类第一类多组输入输出第二类结构体排序第三类枚举加剪枝第四类二分查找或二分答案第五类简单模拟与递推。不要押偏题基础题单的区分度在“谁能把简单题一次写对”。复习时按这五类各挑几道限时写写完对照答案看思路差在哪而不是只看输出对不对。6.5 我的教训早年刷基础题单我总觉得自己“会思路”就等于“能拿分”结果一次模拟赛里三道题样例全过、提交全挂一道多组数据没重置一道排序比较器写了一道二分死循环。从那以后我每次提交前都强制走一遍输入输出、边界和类型检查哪怕题再简单也不跳过。这份在线评测基础题答案笔记更适合当对照表用先自己做再拿答案校正思路最后把易错点写进自己的检查清单。需要这份基础题答案笔记的按文末固定入口自取先挑输入输出和模拟两部分把提交前的动作跑顺再往后刷。希望帮到你。本文还有配套的精品资源点击获取