news 2026/9/28 12:58:53

OJ刷题第五天:13-15题如何突破边界条件与精度陷阱

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
OJ刷题第五天:13-15题如何突破边界条件与精度陷阱

刷 OJ 到第五天,13 到 15 题正好卡在一个门槛上。前几天你还在练“输入两个整数求 a+b”这种热身题,到了这个阶段,题目开始真正考察你写程序的稳定性:逻辑要一次想对,边界条件要想全,提交后面对红色状态要能冷静地定位问题。我先把结论放在这里:第五天做的 13 到 15 题,大概率不是送分题,而是把循环、数组、整型操作以及一点点数学思维揉在一起的综合题。

如果你和我一样,白天有课或有工作,只能抽晚上刷题,那第五天是特别容易放弃的一段。前四天的新鲜感过去了,题目难度开始爬坡,网上搜题解的冲动也最强。我的建议是:13 到 15 题不要贪快,哪怕每天彻底搞懂一道,也比一口气吞下五道有用得多。这篇文章就围绕“第五天 OJ 13 到 15 题”这个阶段,把题型、解法、提交坑位和刷题节奏一次说透。

1. 第五天刷题,13到15题到底在考什么

1.1 从题目序号看题单的递进规律

绝大多数在线评测平台在排新手题单的时候,都会遵循一条看不见的“难度曲线”。刚开始的几道题只考你会不会读入、会不会输出,比如经典的 A+B;接下来几道题开始考分支判断,比如判断闰年、比较大小;再到 10 道题往后,题单会悄悄把循环、数组、多组输入这些内容组合起来考。我刷过的杭电 OJ、郑州轻工业 OJ、东方博宜 OJ 等平台,虽然题目编号不完全一样,但规律基本一致:13 到 15 题正好落在“我能写出代码”向“我能一次写对代码”过渡的区间。

这个过渡不是平台故意刁难人,而是必要的筛选机制。前面的题目像跑步热身,让你熟悉 OJ 的输入输出格式、提交按钮、评测状态这些环境。热身结束后,平台默认你已经知道 CE 是编译错误、WA 是答案错误、TLE 是超时,所以题目不再手把手喂你,开始要求你自己处理“题目没明说但客观上存在”的情况,比如多组输入到底读到哪结束,比如结果要保留几位小数,比如最大值初始化该用多少。这些细节单独拎出来都不难,但凑在一起,就成了第一次劝退点。

1.2 13到15题最常考察的三种能力

第一种是多组输入与循环控制。很多第一次碰到“输入包含多组测试数据,处理到文件结束”的同学会懵,不知道用while (cin >> n)而不是cin >> n。这一阶段反复出现这种读入方式,就是在逼你养成“读入跟着题目描述走,而不是跟着自己的直觉走”的习惯。

第二种是边界条件意识。0、1、最大值、最小值、负数、前导零,这些词听上去很抽象,但 WA 的提交里十有八九挂在它们身上。比如“把一个整数倒序输出,去掉前导零”这道题,输入 120 时输出应该是 21 而不是 021;输入 0 时输出应该是 0 而不是空。这些细节只有你想到了,代码才会对。

第三种是自我调试能力。OJ 不会告诉你错在哪个输入上,你必须学会自己造数据、看输出、猜原因。有人搜“西北农林科技大学 C++ OJ 智能指针”,那是学到数据结构和现代 C++ 才会碰到的东西,13 到 15 题阶段完全用不到,不如先把边界条件练好。

2. 第13到15题的典型题型拆解

不同平台的第 13 到 15 题具体内容可能不同,但这阶段常见的题型高度集中。我把它们归成三类,你对着题单看,大概率能认出来。就算你遇到的题目跟我的描述不完全一样,拆题思路也通用:先读清楚输入是什么、输出要什么格式,再想数据范围,再写代码。

2.1 第13题:数列求和与精度格式化

这类题的典型描述是:输入一个整数 n,求 S = 1 + 1/2 + 1/3 + ... + 1/n 的值,结果保留三位小数。它同时考三件事:累加循环、整数除法和浮点数除法之间的区别、输出格式化。

第一件事不用多说,for循环从 1 加到 n 就完事。第二件事是新手最容易翻车的点:如果你写1 / i,C++ 会按整数除法处理,i 一旦大于 1,结果就是 0,最后累加出来 S 等于 1。要得到正确结果,必须写1.0 / i,让参与除法运算的两个数中至少有一个是浮点数。第三件事是格式化输出,用cout << fixed << setprecision(3)就能把输出固定为小数点后三位。

这类题看着简单,但能一次性 AC 的人并不多。很多人卡在精度上,比如题目要求四舍五入保留三位小数,如果你用单精度float而不是double,数据稍大一点累加误差就会被放大。能用 double 就用 double,不要跟浮点进度较劲。

2.2 第14题:数组最值查找

典型描述是:输入一个正整数 n,然后给出 n 个整数,输出其中的最大值和最小值。这类题考数组操作和比较逻辑,看起来直白,实际上隐藏着初始化陷阱。

新手最常见的写法是:

int maxv = 0; int minv = 0;

如果 n 个整数全是负数,maxv就会一直是 0,答案错误;如果全是正数,minv又输出了 0。正确做法有两种:要么把最大值和最小值都初始化为第一个读入的元素,要么用<climits>头文件里的INT_MAX和INT_MIN。后一种思路更通用,先拿一个很大的数当作最小值候选,再拿一个很小的数当作最大值候选,每读一个数就比一次。

这道题的另一个考点是输入格式:先读 n,再循环读 n 个数。有些同学会把 n 当成第一个要比较的数,导致少读一个数据、拿随机数去比较,最终答案错得莫名其妙。我建议每道题先手动跑一遍样例,把变量每一步的值写在草稿纸上,这种错误基本上当场就能抓出来。

2.3 第15题:数字反转与符号处理

典型描述是:输入一个整数,把它的各位数字反转后输出,要求去掉前导零,负数保留负号。比如输入 -120,输出 -21;输入 0,输出 0。这道题考察整除、取模、负号处理,还顺带考察“前导零”概念,是这一阶段含金量比较高的题。

核心思路是循环“取最后一位,拼到新数字后面”。第一步先保存符号,把负数转成正数处理;第二步用while循环,每次取n % 10,把结果乘以 10 之后加上这一位;第三步把符号乘回去。关于前导零,实际上反转算法天然会处理掉:输入 120,先取出 0,rev变成 0,再取出 2,rev变成 2,再取出 1,rev变成 21,最后输出 21 而不是 021,因为整数类型本身不会保存前导零。

这道题还要留个心眼:如果题目数据范围允许到int的极限,比如 n 是 INT_MIN,那么n = -n会溢出,出现未定义行为。做题前先看题目给的范围,如果 n 的绝对值可能超过int能表示的范围,可以直接用long long来存,省心很多。

3. 完整解题实操展示

光讲题型还是有点虚,我把这三道题的完整代码和实测流程直接放出来。以下代码我在好几个平台上跑过,主要思路一致,个别平台的编译器版本不同,注意用 C++11 或更高版本就没问题。

3.1 三个题目的完整 C++ 代码

第 13 题,数列求和:

#include <iostream> #include <iomanip> using namespace std; int main() { int n; cin >> n; double sum = 0.0; for (int i = 1; i <= n; i++) { sum += 1.0 / i; } cout << fixed << setprecision(3) << sum << endl; return 0; }

注意1.0 / i前面的 1.0 是关键,不能写成 1。fixed控制小数点后的位数,setprecision(3)表示保留三位小数。如果题目要求保留六位,就把 3 改成 6。

第 14 题,数组最值:

#include <iostream> #include <climits> using namespace std; int main() { int n; while (cin >> n) { if (n <= 0) continue; int maxv = INT_MIN; int minv = INT_MAX; for (int i = 0; i < n; i++) { int x; cin >> x; if (x > maxv) maxv = x; if (x < minv) minv = x; } cout << maxv << " " << minv << endl; } return 0; }

这里用while (cin >> n)是因为很多 OJ 题目写的是“多组输入,处理到文件结束”。如果题目只要求处理一组数据,只写一次cin >> n也够,但写成 while 循环也没错,反而能应对额外测试数据。INT_MAX和INT_MIN的引入是这道题最稳妥的初始化方式。

第 15 题,数字反转:

#include <iostream> using namespace std; int main() { long long n; cin >> n; long long sign = 1; if (n < 0) { sign = -1; n = -n; } long long rev = 0; while (n > 0) { rev = rev * 10 + n % 10; n /= 10; } cout << sign * rev << endl; return 0; }

用long long是为了避免INT_MIN取反溢出的问题,比较稳妥。输入 0 时,while 循环不会执行,rev保持 0,输出0,结果正确。

3.2 输入输出样例怎么自测

代码写完别急着提交,先在本地编译器上跑几个样例,确认输出格式跟题目要求完全一致。我以三组典型输入演示一遍:

第 13 题,输入:

3

输出:

1.833

因为 1 + 0.5 + 0.333 约等于 1.833,保留三位小数。

第 14 题,输入:

5 1 2 3 4 5

输出:

5 1

注意最大值和最小值之间是空格,末尾是换行,中间不能有多余的空格或逗号。

第 15 题,输入:

-120

输出:

-21

如果输出成-021或者21都是错的。整数类型不会输出前导零,所以正常反转逻辑就会自动满足“去掉前导零”的要求。

3.3 边界值验证清单

自测样例通过只是第一步,我每次提交前会过一遍边界清单:

  • n 等于 1,比如数列求和只加一项;
  • n 等于 0,如果题目允许,看看程序会不会崩;
  • 全是负数的最值查找,确认 maxv 不会再输出 0;
  • 带负号的数字反转,确认符号没有被丢掉;
  • 结尾带 0 的数字,比如 120,确认输出不是 “021” 而是 21;
  • 可能的最大值、最小值,确认没有溢出。

这组清单看着琐碎,但能挡住 80% 的 WA。很多同学代码逻辑大方向没问题,最后就是挂在“我没想到输入会是负数”这种地方。

4. OJ提交过程中的坑位速查

这一节是实操中最容易卡住的部分。我把自己刷题第五天遇到过的坑、以及在群里看到别人踩过的坑都整理出来,按提交后最常见的状态分类。

4.1 看懂评测状态:AC、WA、PE、TLE、RE、CE

OJ 提交后会返回一个简短的状态,很多人第一次看到错误状态就慌了。其实这些状态含义很固定:

状态含义常见原因
ACAccepted,答案正确无
WAWrong Answer,答案错误逻辑、边界条件、精度问题
PEPresentation Error,格式错误多空格、少换行、输出格式不完全吻合
TLETime Limit Exceeded,超时死循环、算法太慢
RERuntime Error,运行时错误数组越界、除零、空指针
CECompile Error,编译错误语法错误、缺头文件、编译器版本不兼容

其中 PE 最容易让人头大。明明数据对,但因为它要求每组输出之间多打一个空行,或者最后一个数字后面不能有空格,就被判不通过。处理办法是严格复制题面输出样例的格式,不要自己发挥。

4.2 编译错误与运行时错误的处理

编译错误最常见的原因是缺头文件。用了cout没写#include <iostream>,用了INT_MAX没写#include <climits>,用了setprecision没写#include <iomanip>,这些都属于低级但高频的错误。我的习惯是先把整道题要用的功能列出来,再决定包含哪些头文件。

运行时错误里,数组越界是最典型的。如果你开了int a[100],但题目说 n 最大是 1000,越界就是必然的。不要为了省空间把数组开得太小,不确定范围时开大一个量级不会有惩罚。

提示:本地编译器不报错不代表 OJ 上能过。本地运行遇到越界往往会“碰巧正常”,但 OJ 的评测环境可能严格得多,所以数组大小的设置一定要参考题目的数据范围。

4.3 答案错误与格式错误

WA 和 PE 是刷题第五天最常碰到的状态。WA 要考虑边界和精度;PE 要先检查输出格式。我见过一个同学第 14 题输出写成cout << maxv << '\t' << minv << endl;,用制表符代替空格,本地看是整齐,提交后一直 PE,改成空格立刻就 AC 了。

多个测试用例时的换行也是一个常考点。如果题目要求“每组输出占一行”,你就要保证每组之间没有多余空行;如果题目要求“每组输出后跟一个空行”,你还需要额外输出空行。判断方法很简单:看样例输出里两组数据之间有没有空行。样例里没有,你就不要加。

4.4 超时和溢出问题

13 到 15 题阶段遇到 TLE 的概率比较低,但不代表不会遇到。最常见的原因是while循环条件写错,导致死循环。比如判断输入是否结束时,你写的是while (cin >> n != 0),语义容易混乱;正确写法是while (cin >> n),读入失败循环自然结束。

溢出问题也要提前想。第 13 题如果 n 很大,double一般够用;但如果题目换成阶乘求和,int很快就爆了,要用long long,必要的时候甚至要用到高精度。做题前先估一下最坏情况下的数值大小,这个习惯应该从第 13 题就开始养。

5. 刷题节奏与复盘方法

5.1 错题本怎么写才有用

第五天刷题,错题本的价值开始体现。不要直接把别人的 AC 代码抄一遍贴上去,那样下次还是不会。我的错题本每道题只写三行:题目属于什么类型,我在哪里想错了,正确思路里最关键的判断是什么。

比如第 15 题如果我 WA 了,我会写:“类型:数字反转;错误点:没有判断负数,对 INT_MIN 取反溢出;关键思路:先用 long long,再单独存符号。”下次遇到类似题目,翻一下两秒钟就能想起来,比重新看一遍长篇代码有用得多。

这也侧面回答了为什么我不建议搜“郑州轻工业 OJ 答案”“东方博宜 OJ 答案 1065”这类关键词。别人给出的代码不一定理解你的错误点,直接抄过来,你只是拿到了一个 AC,失去了发现问题、修正思路的完整训练过程。真正想要答案,就把题目类型、自己的代码和错误提示记下来,自己对比解决。

5.2 一天刷多少题更合适

如果你每天能保证一到两小时,我的建议是每天 3 到 5 道新题,其中至少 1 道是自己花 20 分钟以上硬想出来的。第五天做到 13 到 15 题,正好处在这个量级。如果时间不够,只做一道难一点的题、把它的边界情况和输出格式完全吃透,也好过刷十道简单题。

还要提醒一点:刷题最怕的不是做得慢,而是断档。中间落了一两天,回来发现判断输入的方式忘了、格式化输出又不熟,心态很容易崩。宁可每天只写十几行代码,也要把“每天碰一碰 OJ”这个习惯续住。等过了第十天、第二十天,回看第五天这个阶段,你会发现自己对 WA 的恐惧已经淡了很多。

6. 关于第五天刷题的三点体会

最后说几句个人感受,也算不上总结,只是我在带着不少人做过这个阶段之后,最想强调的三件事。

第一,抄题解的时代在第五天就应该结束。前面几题你还可以通过模仿建立手感,13 到 15 题开始,模仿不来了,你必须有自己排错的能力。每 WA 一次,都对题目逻辑多一层理解,这种积累是题解给不了的。

第二,不要觉得“第五天才做到 15 题”很慢。OJ 刷题比的不是数量,而是稳定性和熟练度。我见过有人一天刷二十道,结果连循环边界都没真正理解;也见过有人一周只刷十几道,但每一道都能讲清楚为什么这么写。后者到了后期题目变难时,适应速度反而更快。

第三,把边界值测试当成肌肉记忆。这阶段练的三道题型,本质上都在反复训练同一件事:你写的代码能不能应付极端输入。这个习惯越早养成,后面遇到字符串、数据结构、搜索算法时就越省心。我在实际刷题中踩过几次坑之后,已经形成条件反射,代码写完先跑 0、1、负数、最大值四组数据,再跑正常样例。你也值得试试。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/28 12:58:06

C盘爆满不用慌:十招深度清理与空间迁移实战指南

C盘又飘红了&#xff1f;别急着重装系统&#xff0c;也别一上来就下载各种“清理大师”。我在给同事、朋友救急的过程中总结了一套从排查到清理的完整打法&#xff0c;这篇文章把十招都给你拆开讲透&#xff0c;每一招都附上操作细节和避坑提醒&#xff0c;照着做基本能把C盘从…

作者头像 李华
网站建设 2026/9/28 12:56:56

OCC场景下分段Clock Tree设计与Innovus实现

1. 项目概述&#xff1a;为什么分段长clock tree是OCC场景下绕不开的硬骨头SoC芯片设计里&#xff0c;时序问题从来不是靠堆资源能解决的&#xff0c;尤其当OCC&#xff08;On-Chip Clocking&#xff09;电路遇上高扇出、长距离、多电压域的复杂布局时&#xff0c;传统单根cloc…

作者头像 李华
网站建设 2026/9/28 12:56:38

nRF52840 Dongle BLE抓包全攻略:固件烧录到Wireshark实战

BLE 抓包这件事&#xff0c;说难不难&#xff0c;说简单也真能卡住人。我见过太多人买了 nRF52840 Dongle&#xff0c;插上电脑发现设备管理器里是个未知设备&#xff0c;或者 Wireshark 里根本找不到 nRF Sniffer 接口&#xff0c;折腾一晚上连个广播包都没抓到。这篇就把从固…

作者头像 李华
网站建设 2026/9/28 12:56:38

KMeans聚类算法原理、Python实现与实战避坑指南

简介&#xff1a;KMeans聚类算法是无监督学习中的经典方法&#xff0c;这份资源面向机器学习初学者与数据分析人员&#xff0c;结合Python与scikit-learn完整演示了从数据加载、标准化、模型训练、预测到可视化的流程&#xff0c;并讨论初始质心选择、K值设定等关键问题。压缩包…

作者头像 李华
网站建设 2026/9/28 12:55:53

手把手教你用OpenCode Skills实现网页书签AI查询与自动化

我最早被OpenCode圈粉&#xff0c;是因为它把“Skills”这个概念做得足够接地气——不用改模型、不用重训AI&#xff0c;只要往技能目录里塞一个带描述的文件和一段脚本&#xff0c;AI就突然会干一件新事。前阵子我把浏览器里两千多条书签翻出来处理&#xff0c;顺手就做成了一…

作者头像 李华
网站建设 2026/9/28 12:54:42

JavaEE+MySQL个人博客系统:从环境搭建到答辩全攻略

简介&#xff1a;这是一套面向高校学生与Java进阶学习者的个人博客系统完整项目资料&#xff0c;可作为毕业设计、课程设计、大作业或工程实训的参考方案&#xff0c;帮助解决从需求梳理到答辩展示的全流程问题。资源包约179.66MB&#xff0c;涵盖源码、数据库SQL脚本、论文、答…

作者头像 李华