攻克GESP一级核心算法:循环与条件判断的完美结合备考GESP C++一级的同学们,你们是否曾为如何高效筛选数据而苦恼?今天,我们就来深入解析两道经典的真题------《找因数》(2024.03)和《小明的幸运数》(2023.09)。这两道题目看似场景迥异,实则都考查了一个编程的核心能力:如何利用循环结构结合条件判断,对数据进行精确筛选和计算。理解这个能力,是培养计算思维、解决实际问题的重要基石。
一、真题对比:从"找因数"到"幸运数"GESP一级:2024.03 - 找因数【提交】
https://www.luogu.com.cn/problem/B3953
【问题描述】小杨同学最近刚刚学习了因数的概念,具体来说,如果一个正整数 可以被另一个正整数 整除,那么我们就说 是 的因数。如6可以被2整除,因此2是6的因数。请编写一个程序,从小到大输出正整数 的所有因数。如输入6,则逐行输出1、2、3、6。【输入描述】输入一行一个正整数 。保证 【注意:不必反应到编程代码之中】。【输出描述】输出若干行,为 的所有因数,从小到大排列。【特别提醒】在常规程序中,输入、输出时提供提示是好习惯。但在本场考试中,由于系统限定,请不要在输入、输出中附带任何提示信息。【样例输入1】1
【样例输出1】1
【样例输入2】6
【样例输出2】1
2
3
6
【样例输入3】10
【样例输出3】1
2
5
10
参考答案:
cpp
/*
* [GESP202403 一级] 找因数
* https://www.luogu.com.cn/problem/B3953
*/
#include <iostream>
usingnamespacestd;
int main()
{
int a;
cin >> a;
for (int i = 1; i <= a; i++)
{
if (a % i == 0)
{
cout << i << endl;
}
}
return0;
}
GESP一级:2023.09 - 小明的幸运数【提交】
https://www.luogu.com.cn/problem/B3864
【问题描述】所有个位数为 的正整数,以及所有 的倍数,都被小明称为"幸运数"。小明想知道正整数 和 之间(包括和)所有 幸运数的和,你能帮帮他吗?【输入描述】输入3行。第一行包含一个正整数 ,第二行包含一个正整数 ,第三行包含一个正整数 。约定 ,。
【输出描述】输出1行,符合题意的幸运数之和。【样例输入1】7
1
10
【样例输出1】7
【样例解释1】1和10之间共有1个7幸运数:7。因为7既是7的倍数,个位数又为7。因此,结果为7。【样例输入2】7
10
20
【样例输出2】 31
【样例解释2】10和20之间共有2个7幸运数:14和17。14是7的倍数,17的个位数为7。因此,结果为31。参考答案:/*
- GESP202309 一级 小明的幸运数
- https://www.luogu.com.cn/problem/B3864
*/
cpp
# include<iostream>
usingnamespacestd;
int main()
{
int k = 0, l = 0, r = 0,sum=0;
cin >> k >> l >> r;
for (int i = l;i <= r;i++)
{
if (i % 10 == k || i % k == 0)
sum += i;
}
cout << sum;
return0;
}
二、知识精讲:循环枚举与条件筛选的范式1. 循环枚举的基本模式这两道题都采用了循环枚举的解题思路,这是计算机科学中最基础、最常用的算法思想之一。通用范式:初始化变量
cpp
for (遍历范围) {
if (满足条件) {
执行相应操作
}
}
输出结果
关键要素:遍历范围:确定循环的起止点条件判断:筛选符合要求的数据操作处理:对筛选出的数据进行处理2. 条件判断的构建技巧在《找因数》中,条件判断是简单的整除关系判断:
if (N % i == 0)
在《小明的幸运数》中,条件判断更加复杂,包含了逻辑运算符:if (i % 10 == k || i % k == 0)
条件构建的进阶:简单条件:单个关系判断复合条件:使用逻辑与(&&)、逻辑或(||)连接多个条件嵌套条件:if-else if-else结构处理多种情况3. 取模运算的妙用取模运算(%)在这两道题中都扮演了关键角色:在《找因数》中:N % i == 0 判断i是否是N的因数体现了"整除"的数学概念在《小明的幸运数》中:i % 10 == k 判断个位数是否为ki % k == 0 判断i是否是k的倍数展现了取模运算在数字分析中的多种应用
三、从具体实现到抽象思维
- 问题抽象的三个层次层次一:理解问题(题目描述的是什么)《找因数》:找出所有能整除N的数《小明的幸运数》:找出满足特定条件的数并求和层次二:数学建模(如何用数学语言描述)《找因数》:找出所有满足 N mod i = 0 的i《小明的幸运数》:找出所有满足 (i mod 10 = k) ∨ (i mod k = 0) 的i层次三:编程实现(如何用代码表达)选择合适的循环结构构建正确的条件表达式设计合理的输出格式
- 效率与优化的思考虽然这两道题的数据范围较小(N≤1000),可以采用简单的遍历方法,但我们需要思考:如果数据范围增大怎么办?《找因数》:可以优化到只遍历1到√N《小明的幸运数》:可能需要更高效的算法这种"从简单到优化"的思考过程,正是算法思维的重要体现。
四、知识扩展:更多应用场景掌握了循环枚举与条件筛选的思想,我们可以解决一大类问题:
在这里插入代码片1. 数字属性判断// 判断素数
cpp
bool isPrime = true;
for (int i = 2; i * i <= n; i++) {
if (n % i == 0) {
isPrime = false;
break;
}
}
- 区间统计// 统计区间内质数的个数
cpp
int count = 0;
for (int i = L; i <= R; i++) {
if (isPrime(i)) { // 假设有isPrime函数
count++;
}
}
- 数字分解// 将一个数分解为质因数
cpp
int temp = n;
for (int i = 2; i * i <= temp; i++) {
while (temp % i == 0) {
cout << i << " ";
temp /= i;
}
}
if (temp > 1) cout << temp;
五、编程思维的核心:模式识别与问题转化
- 模式识别能力通过对比这两道题,我们可以发现:相同的模式:都需要遍历一个区间都需要对每个元素进行条件判断都需要对符合条件的元素进行处理不同的细节:遍历的区间不同(1到N vs L到R)判断的条件不同(整除 vs 个位数或倍数)处理的方式不同(输出 vs 累加)
- 问题转化技巧许多复杂问题都可以转化为"循环枚举+条件筛选"的模式:原问题:找出所有满足特定条件的元素转化后:遍历所有可能元素,用条件判断筛选这种转化能力,是解决编程问题的关键。
六、思考与总结《找因数》和《小明的幸运数》虽然题目背景和具体要求不同,但它们都考查了同一个核心编程能力:用循环结构结合条件判断对数据进行筛选和处理。这背后体现的编程思维包括:抽象建模:将实际问题转化为可计算的数学模型算法设计:选择合适的遍历策略和判断条件边界处理:确保遍历的完整性和条件的准确性代码实现:将算法思想转化为正确的C++代码掌握这个知识点,不仅能够应对考试中的筛选类问题,更重要的是培养了用计算机思维解决实际问题的能力。这是从"学习编程语法"到"应用编程思维"的重要跨越。