info
GESP C++ 2 级综合提升:数学问题
本章是"分支 + 循环嵌套"的综合练手,覆盖等差/等比数列、质数判断、阶乘、最大公约数等高频模型。其中质数判断、辗转相除法(GCD)更接近 3 级算法难度,但作为 2 级"综合案例"巩固非常合适。涉及数学函数时请回看第 16 章。
第19章 数学问题
本章讲解竞赛与考试高频数学模型:等差、等比数列,质数合数,阶乘,因数、公约数相关算法。
19.1 数列
19.1.1 等差数列
定义:后项减前项差值固定(公差 d)
- 通项:
- 前 n 项和:
示例代码:输出首项 2,公差 3,共 5 项
#include <iostream>
using namespace std;
int main()
{
int a1 = 2, d = 3, n = 5;
for (int i = 0; i < n; i++)
{
int term = a1 + i * d;
cout << term << " ";
}
return 0;
}
19.1.2 等比数列
定义:后项÷前项比值固定(公比 q,q≠0)
- 通项:
- 前 n 项和: 时
示例代码:首项 2,公比 3,4 项
#include <iostream>
using namespace std;
int main()
{
int a1 = 2, q = 3, n = 4;
int t = a1;
for (int i = 0; i < n; i++)
{
cout << t << " ";
t *= q;
}
return 0;
}
19.2 质数与合数
19.2.1 质数(素数)
大于 1,只能被 1 和自身整除。 判断思路:从 2 遍历到 ,存在能整除则不是质数。
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
int n = 7;
bool isPrime = true;
if (n <= 1) isPrime = false;
else
{
for (int i = 2; i <= sqrt(n); i++)
{
if (n % i == 0)
{
isPrime = false;
break;
}
}
}
cout << boolalpha << isPrime;
return 0;
}
19.2.2 合数
大于 1 且不是质数;1 既不是质数也不是合数。
tip
质数判断优化点 循环只需到 (约 2.6),不用到 ,大幅提速。这是 2 级"综合案例"里最能体现循环优化思维的题。
19.3 阶乘
定义 ,规定 。
注意:数值增长极快,使用 long long 防止溢出。
#include <iostream>
using namespace std;
int main()
{
int n = 5;
long long res = 1;
for (int i = 1; i <= n; i++)
res *= i;
cout << res;
return 0;
}
19.4 因数
能整除该数的整数;遍历 1~num,取能整除的数。
19.5 公因数与最大公因数(GCD)
19.5.1 辗转相除法(欧几里得算法)
核心:gcd(a, b) = gcd(b, a % b),余数为 0 时 b 是最大公约数。
#include <iostream>
using namespace std;
int main()
{
int a = 24, b = 18;
int t;
while (b != 0)
{
t = a % b;
a = b;
b = t;
}
cout << a;
return 0;
}
19.5.2 多个数最大公约数
先求前两个的 GCD,再和下一个数字求 GCD,循环处理。
19.6 补充要点
- 质数判断循环只需到平方根,大幅提速;
- 阶乘必须用
long long,int极易溢出; - 最小公倍数 = 两数乘积 / 最大公约数;
- 所有公因数一定是最大公因数的约数。
caution
阶乘溢出是高频错误
int 存阶乘:13! 就超过 int 上限(约 21 亿)。12! = 479001600 还能存,13! 溢出。凡是阶乘、连乘,默认用 long long。
练习题(2 级单选风格)
- 判断一个整数 n 是否为质数时,试除循环只需进行到?
- A. n
- B. n/2
- C. √n(sqrt(n))
- D. n-1
- 用
int存储 13!(阶乘)会?- A. 正常存储
- B. 数值溢出
- C. 变成 0
- D. 编译报错
- 求两数的最大公约数(GCD)最常用的方法是?
- A. 累乘
- B. 辗转相除法(欧几里得算法)
- C. 逐次相加
- D. 取平方根
- 两数的最小公倍数 LCM(a,b) 等于?
- A. a × b
- B. a × b ÷ GCD(a,b)
- C. GCD(a,b)
- D. max(a,b)
- 下列代码执行后输出什么?
int f = 1;for (int i = 1; i <= 5; i++) f *= i;cout << f;
- A. 120
- B. 5
- C. 25
- D. 15
参考答案(点击展开)
- C — 若 n 有因数,必有一个 ≤ √n;试除到 √n 即可,效率远高于试到 n。
- B —
int上限约 21 亿,13!=6227020800 远超上限,发生溢出;应使用long long。 - B — 辗转相除法:反复
a = a % b交换,直到余数为 0,当前除数即 GCD,高效通用。 - B — 两数的乘积等于 GCD 与 LCM 的乘积,故 LCM = a×b÷GCD(先除后乘防溢出)。
- A — 循环算 1×2×3×4×5 = 120,即 5 的阶乘。