2026/10/18 8:30:59

GESP 2023年6月 找素数 题解|循环结构详细讲解

GESP 2023年6月 找素数 题解|循环结构详细讲解 这是 GESP 2023年6月 的一道循环结构题。题目本身不难但有几个地方特别容易出错我把踩过的坑都写出来希望能帮刚学到这里的朋友少走弯路。题目来源ACGO A46102 2023年6月 二级赛事场次2023年6月 二级一、题目信息题目名称找素数赛事场次2023年6月 二级难度定位二级涉及知识点循环结构题目链接https://www.acgo.cn/problemset/info/46102坑点预警这里最容易失分循环三要素初值、条件、步进循环不变式。题意简述小明刚刚学习了素数的概念如果一个大于 1 的正整数除了 1 和它自身外不能被其他正整数整除则这个正整数是素数。现在小明想找到两个正整数A和B之间包括A和B有多少个素数前置知识做题之前我们先把几个关键概念说清楚这样后面的代码才好理解。for 循环的标准写法for(int i1;in;i)表示 i 从 1 递增到 n每次循环体执行完 i 自动加 1。竞赛中我们习惯从 1 开始计数这样可以避免下标越界的麻烦。while 循环适合循环次数不确定的场景只要条件成立就一直执行写的时候一定要确保循环变量会被修改否则会死循环。二、思路分析先看清楚题目要我们做什么把题目读两遍我们提取出关键信息输入是什么、要输出什么、有哪些约束条件。这道题考查的是循环结构属于这类题里比较基础的一道把题目要求一步步翻译成代码逻辑就能解决。我的思考过程读完题之后我的第一反应是这样的【题目大意】统计整数 A 到 B 范围内的素数个数数据范围不超过 1000。【考纲知识点】多层分支/循环结构二级【解题思路】枚举 A 到 B依次检查每个数是不是素数。用变量 isPrime 表示当前枚举的数 n 是否为素数初始化为 true如果找到了除了 1 和 n 以外的因数则把 isPrime 赋值为 false。寻找 n 的因数时只需要枚举 2 到根号 n。因为如果 n 有一个大于根号 n 的因数 k那么就一定存在一个小于根号 n 的因数 n/k。使用变量 cnt 记录素数的个数最终输出即可。【参考程序】需要说明的是上面这个思路是把题目要求直译成代码得到的没有用到什么高级技巧。对于这类基础题读准题意加写对边界比追求巧妙解法更重要因为考试里这种题是必须拿满分的。三、完整代码 逐行注释#include iostream using namespace std; int main() { int a 0, b 0, cnt 0; cin a b; // 读入 for (int n a; n b; n) { // 遍历 bool isPrime true; // 假设初始 isPrime 的值为 true // 利用因数成对存在的性质遍历较小的因数判断 n 是否为素数 for (int i 2; i * i n; i) { // 遍历 if (n % i 0) { // 判断 //若发现 n 存在因数更改标记 isPrime 并跳出循环 isPrime false; break; } } //题目规定 n 不会为 1否则要特殊判断1的情况 if (isPrime) // 判断 cnt; //统计素数个数 } cout cnt endl; // 输出 return 0; }四、代码分段拆解代码不长但每一段都有讲究我们分段拆开看。第一步引入头文件#include iostream using namespace std;#include iostream提供输入输出功能using namespace std;让我们能直接写cin、cout而不用加前缀。这两行是几乎所有 C 程序的开头照写即可。第二步读入数据cin a b;注意变量的类型要能装下题目的数据。数据可能超过 21 亿时要改用long long。第三步核心处理逻辑for (int n a; n b; n) { for (int i 2; i * i n; i) {这一段是整道题的关键也是循环结构的体现。看循环的三个要素从哪里开始、什么时候结束、每次怎么变化。这三个要素任何一个写错结果都会不对。第四步按要求输出cout cnt endl;输出格式必须和题目要求的完全一致。很多同学算法完全正确却因为少了一个换行或者空格多寡不对而 WA这种分丢得最可惜。五、实例模拟光看代码可能还不够直观我们用题目的样例实际跑一遍看看程序是怎么走的。以题目的第一组样例为例样例输入2 10样例输出4把这份输入代进代码程序会先把数据依次读入然后进入循环逐个判断把满足条件的值累积起来最后按格式输出。建议你对照着代码在纸上走一遍前两次循环确认自己对每一步的理解都和程序一致。题目另外还给了 1 组样例做完之后建议把剩下的样例都跑一遍全部通过再提交能避开大部分边界问题。六、踩坑总结下面是做这道题时最容易出错的地方对照自己的代码检查一下变量类型选错虽然本题范围不大但养成习惯——凡是不确定范围时累加变量一律用long long成本为零但能保命。取余与整除混淆a % b取的是余数a / b取的是整数商两个完全不同。判断倍数关系用a % b 0写成a / b 0就全错了。区间边界取错题目说「L 到 R 之间包括两端」循环就要写for (int i L; i R; i)。写成i R会漏掉最后一个数这是最常见的失分点。循环起点搞错题目说的是「正整数」循环要从 1 开始而不是从 0 开始差一个数就是 WA。输出格式不符题目要求输出几行就输出几行行末换行、数字之间的空格都要严格对齐算法对了但格式错了同样判 WA这种分丢得最冤。特殊情况没特判把最小数据、最大数据、答案恰好等于 0 的情况各测一遍。特别是边界输入出题人最喜欢在这里设陷阱。七、知识点拓展最后总结一下这道题带给我们的通用经验本题考查循环结构的基本写法这类题在考试中属于必得分项要练到能默写。写完代码后建议自己造几组边界数据测试特别是最小值和最大值。同一知识点在不同场次反复出现把这道题的写法吃透后面遇到同类题可以直接套用。八、适用人群如果你已经掌握循环结构的基本写法这道题可以用来巩固手感。以上就是这道题的全部内容。这个系列会按考试场次逐题更新觉得有帮助的话可以关注一下也欢迎在评论区留下你的解法。