2026/10/18 8:30:59

GESP 2023年9月 数字黑洞 题解|循环结构详细讲解

GESP 2023年9月 数字黑洞 题解|循环结构详细讲解 这道题是 GESP 2023年9月 的真题难度定位在 二级。别看它代码不长里面对循环结构的考查很到位我第一次做的时候也踩了坑。下面把完整思路梳理一遍。题目来源ACGO A46099 2023年9月 二级赛事场次2023年9月 二级一、题目信息题目名称数字黑洞赛事场次2023年9月 二级难度定位二级涉及知识点循环结构题目链接https://www.acgo.cn/problemset/info/46099坑点这题失分基本都在这循环三要素初值、条件、步进循环不变式。题意简述给定一个三位数要求各位不能相同。例如 352 是符合要求的 112 是不符合要求的。将这个三位数的三个数字重新排列得到的最大的数减去得到的最小的数形成一个新的三位数。对这个新的三位数可以重复上述过程。神奇的是最终一定会得到 495 试试看重新排列 352 得到的最大数为 532 最小数为 235 它们的差是 297 变换 297 得到 972-279693 变换 693 963-369594 变换 594 954-459495 。因此 经过 4 次变换得到了 。现在输入的三位数你能通过编程得出这个三位数经过多少次变换能够得到 495 吗前置知识这道题用到的前置知识不多我们先把它补齐即使你刚学到这里也能看懂。for 循环的标准写法for(int i1;in;i)表示 i 从 1 递增到 n每次循环体执行完 i 自动加 1。竞赛中我们习惯从 1 开始计数这样可以避免下标越界的麻烦。while 循环适合循环次数不确定的场景只要条件成立就一直执行写的时候一定要确保循环变量会被修改否则会死循环。二、思路分析先看清楚题目要我们做什么把题目读两遍我们提取出关键信息输入是什么、要输出什么、有哪些约束条件。这道题考查的是循环结构属于这类题里比较基础的一道把题目要求一步步翻译成代码逻辑就能解决。解题步骤拆解按题目要求读入全部输入数据。按题意逐项处理这一步是核心要保证每一步都对应题目里的一句话。按题目规定的格式输出结果。需要说明的是上面这个思路是把题目要求直译成代码得到的没有用到什么高级技巧。对于这类基础题读准题意加写对边界比追求巧妙解法更重要因为考试里这种题是必须拿满分的。三、完整代码 逐行注释#include iostream using namespace std; int main() { // 读取输入的三位数 int n 0; // 初始化 cin n; // 读入 // 循环进行变换直到得到495 for (int t 0; ; t) { // 遍历 // 如果当前的三位数已经是495则输出变换次数并结束循环 if (n 495) { // 判断 cout t endl; // 输出 break; } // 分别提取当前三位数的各位数字 int m0 n % 10, m1 n / 10 % 10, m2 n / 100; int tmax 0, tmin 0; // 按照规定重新排列数字得到最大值和最小值 if (m0 m1 m1 m2) { // 判断 tmax m0 * 100 m1 * 10 m2; tmin m2 * 100 m1 * 10 m0; } else if (m0 m2 m2 m1) { tmax m0 * 100 m2 * 10 m1; tmin m1 * 100 m2 * 10 m0; } else if (m1 m0 m0 m2) { tmax m1 * 100 m0 * 10 m2; tmin m2 * 100 m0 * 10 m1; } else if (m1 m2 m2 m0) { tmax m1 * 100 m2 * 10 m0; tmin m0 * 100 m2 * 10 m1; } else if (m2 m0 m0 m1) { tmax m2 * 100 m0 * 10 m1; tmin m1 * 100 m0 * 10 m2; } else { // m2 m1 m1 m0 tmax m2 * 100 m1 * 10 m0; tmin m0 * 100 m1 * 10 m2; } // 计算新的三位数并更新 n n tmax - tmin; } return 0; }四、代码分段拆解为了看得更清楚我们把代码按功能分成几段解释。第一步引入头文件#include iostream using namespace std;#include iostream提供输入输出功能using namespace std;让我们能直接写cin、cout而不用加前缀。这两行是几乎所有 C 程序的开头照写即可。第二步读入数据cin n;注意变量的类型要能装下题目的数据。数据可能超过 21 亿时要改用long long。第三步核心处理逻辑for (int t 0; ; t) {这一段是整道题的关键也是循环结构的体现。看循环的三个要素从哪里开始、什么时候结束、每次怎么变化。这三个要素任何一个写错结果都会不对。第四步按要求输出cout t endl;输出格式必须和题目要求的完全一致。很多同学算法完全正确却因为少了一个换行或者空格多寡不对而 WA这种分丢得最可惜。五、实例模拟下面用样例数据走一遍流程你能看到每一步变量是怎么变化的。以题目的第一组样例为例样例输入352样例输出4把这份输入代进代码程序会先把数据依次读入然后进入循环逐个判断把满足条件的值累积起来最后按格式输出。建议你对照着代码在纸上走一遍前两次循环确认自己对每一步的理解都和程序一致。六、踩坑总结下面是做这道题时最容易出错的地方对照自己的代码检查一下变量类型选错虽然本题范围不大但养成习惯——凡是不确定范围时累加变量一律用long long成本为零但能保命。输出格式不符题目要求输出几行就输出几行行末换行、数字之间的空格都要严格对齐算法对了但格式错了同样判 WA这种分丢得最冤。特殊情况没特判把最小数据、最大数据、答案恰好等于 0 的情况各测一遍。特别是边界输入出题人最喜欢在这里设陷阱。七、知识点拓展最后总结一下这道题带给我们的通用经验本题考查循环结构的基本写法这类题在考试中属于必得分项要练到能默写。写完代码后建议自己造几组边界数据测试特别是最小值和最大值。同一知识点在不同场次反复出现把这道题的写法吃透后面遇到同类题可以直接套用。八、适用人群适合正在备考 二级、想确认自己循环结构基础是否扎实的同学。这道题就讲到这里。我会持续更新各场次真题的详细拆解需要系统复习的同学可以关注这个系列。有问题欢迎评论区讨论。