☰
GESP2026年9月认证C++二级( 第三部分编程题(1、直角三角形))精讲
2026/10/1 7:56:36 网站建设 项目流程


一、先把题目变成一个“小故事”🏰

小双正在研究一种神奇的数字数列。

他发现:

如果连续的两个数字是直角三角形的两条直角边,那么下一个数字就可以当作斜边。

还记得勾股定理吗?

如果一个直角三角形:

/| / | / | b / | /____| a

那么:

所以:


二、数列规则到底是什么?

题目规定:

第1项 = a 第2项 = b 第3项 = √(第1项² + 第2项²) 第4项 = √(第2项² + 第3项²) 第5项 = √(第3项² + 第4项²)

是不是很像:

🧙‍♂️“前两个数字合体,召唤出下一个数字!”


三、先看题目的样例

输入:

3.0 4.0 10.0

意思是:

第一项 = 3 第二项 = 4 上限 = 10

题目要求:

第几项开始超过 10?

题目给出的数列过程是:3、4、5、约6.403、约8.124、约10.344……,因此答案是第6项。

我们亲自算一遍。


四、第一关:第3项怎么算?

现在:

第1项 = 3 第2项 = 4

根据规则:

第3项=

也就是:

= 5

所以:

3 4 5

五、第二关:第4项怎么算?

现在前两个数字变成:

4 5

所以:

第4项 =

大约:

6.403

于是:

3 4 5 6.403

六、继续!

第5项:

大约:

8.124

第6项:

大约:

10.344

终于:

10.344 > 10

🎉 找到了!

所以答案:

6

这正是题目的样例输出。


七、现在问题来了:C++ 怎么写?

我们刚才是人脑在算:

3 → 4 → 5 → 6.403 → 8.124 → 10.344

但是计算机不会自己猜。

我们必须告诉它:

“只要当前数字还没有超过上限,就继续召唤下一个数字!”

这时候就要请出我们的老朋友:

⭐while循环


八、先设计变量

我们需要三个主要变量:

double a, b, U;

分别表示:

a → 当前的前一个数字 b → 当前的最后一个数字 U → 上限

例如开始:

a = 3 b = 4 U = 10

九、为什么只需要两个数字?

这是这道题非常值得孩子理解的地方。

我们原来的数列好像很长:

3 4 5 6.403 8.124 10.344 ……

是不是需要把所有数字都存下来?

不需要!

因为计算下一个数字的时候,我们只需要:

前一个 + 最后一个

例如:

3 4 ↓ 5

得到 5 后:

4 5 ↓ 6.403

再得到:

5 6.403 ↓ 8.124

所以我们只需要两个“数字盒子”:

┌──────┐ │ a │ ├──────┤ │ 3 │ └──────┘ ┌──────┐ │ b │ ├──────┤ │ 4 │ └──────┘

每次产生新数字以后:

旧的 b 变成新的 a,新数字变成新的 b。

这就是整个程序最关键的“换位魔法”!✨


十、核心公式怎么写?

数学公式:

C++:

double t = sqrt(a * a + b * b);

这里:

sqrt()

就是:

求平方根

例如:

sqrt(25)

得到:

5.0

所以:

sqrt(a * a + b * b)

就是把勾股定理直接变成 C++。


十一、最关键的“换位魔法”🔄

假设:

a = 3 b = 4

先算:

double t = sqrt(a * a + b * b);

得到:

t = 5

现在我们希望:

a = 4 b = 5

所以:

a = b; b = t;

变成:

原来: a → 3 b → 4 t → 5 执行 a = b: a → 4 b → 4 t → 5 执行 b = t: a → 4 b → 5 t → 5

于是:

a = 4 b = 5

下一轮就可以继续算:


十二、但是有一个问题:什么时候停止?

题目问的是:

第几项开始超过 U?

所以我们可以一直检查:

while (b <= U)

意思是:

“只要目前的最后一项还没有超过上限,就继续往下算。”

一旦:

b > U

就停止!


十三、为什么ans一开始是 1?

这个地方很容易让初学者疑惑。

程序:

int ans = 1;

为什么不是:

int ans = 0;

因为一开始我们手里已经有:

第1项 a 第2项 b

我们要计算的是:

到底第几项超过上限。

所以程序用ans来记录当前已经走到第几项。


情况1:第一项已经超过上限

例如:

a = 20 b = 30 U = 10

第1项:

20 > 10

答案就是:

1

所以:

int ans = 1;

然后:

if (a <= U) ans++;

如果第一项没有超过上限,才继续把答案位置往后移动。


十四、把整个程序“翻译成人话”

参考程序是:

#include <iostream> #include <cmath> using namespace std; int main() { double a, b, U; cin >> a >> b >> U; int ans = 1; if (a <= U) ans++; while (b <= U) { ans++; double t = sqrt(a * a + b * b); a = b; b = t; } cout << ans << endl; return 0; }

这是题目给出的参考程序。

现在我们把它解析一下。


第1步:准备三个盒子

double a, b, U;

三个盒子:

a → 前一个数字 b → 当前数字 U → 上限

第2步:输入

cin >> a >> b >> U;

例如:

3 4 10

于是:

a = 3 b = 4 U = 10

第3步:准备答案

int ans = 1;

从第1项开始数。


第4步:看看第1项是否超过上限

if (a <= U) ans++;

因为:

3 <= 10

所以:

ans = 2

意思是:

“第1项没有超,现在至少要继续看第2项。”


十五、进入while大冒险!🚀

现在:

a = 3 b = 4 U = 10 ans = 2

判断:

while (b <= U)

也就是:

4 <= 10

成立!

继续!


第一次循环

ans = 3

计算:

= 5

所以:

t = 5

然后:

a = b; b = t;

得到:

a = 4 b = 5

第二次循环

检查:

5 <= 10

成立。

所以:

ans = 4

计算:

于是:

a = 5 b = 6.403

第三次

6.403 <= 10

成立。

所以:

ans = 5

计算:

b ≈ 8.124

第四次

8.124 <= 10

成立。

所以:

ans = 6

继续计算:

b ≈ 10.344

十六、终于遇到“大门”🚪

现在:

b ≈ 10.344 U = 10

检查:

b <= U

也就是:

10.344 <= 10

❌ 不成立!

所以while停止。

此时:

ans = 6

输出:

6

十七、给同学们画一张“变量变化表”

阶段abans动作
开始342两项都还没超过10
第1次453生成5
第2次56.4034生成6.403
第3次6.4038.1245生成8.124
第4次8.12410.3446生成10.344
停止—10.3446超过10

这样一看,整个程序就不神秘了。


十八、这道题真正考什么?

千万不要认为这题只是考:

“会不会sqrt()。”

其实它考了至少5个知识点。

①double

因为数列里面有:

6.403... 8.124... 10.344...

有小数,所以不能使用普通的:

int

而要使用:

double

②sqrt()

sqrt(x)

表示:

求 x 的平方根。

需要:

#include <cmath>

③while

因为我们不知道需要计算多少次。

可能:

第3项超过

也可能:

第10项超过

甚至:

第100项超过

所以非常适合:

while (...)

④ 变量更新

这是本题最重要的编程思想之一:

a = b; b = t;

它不是随便写的。

而是在做:

旧的“最后一个” ↓ 变成 新的“前一个” 新计算出来的数字 ↓ 成为 新的“最后一个”

⑤ “什么时候停止”

while (b <= U)

这是算法思想:

没超过 → 继续

超过了 → 停止

这叫做循环的终止条件。


十九、同学们最容易犯的4个错误 ⚠️

错误1:把a、b一直不更新

如果写成:

while (b <= U) { double t = sqrt(a*a+b*b); }

那么:

a、b

一直没变化!

程序可能一直算:

3和4 3和4 3和4 3和4 ……

💥 死循环!

所以:

a = b; b = t;

非常重要。


错误2:使用int

如果:

int a, b;

那么小数会被丢掉,可能导致错误。

本题应该使用:

double

错误3:把公式写错

正确:

sqrt(a * a + b * b)

不是:

sqrt(a * a + b)

更不是:

sqrt(a + b) * sqrt(a + b)

一定要记住:

a2+b2\boxed{\sqrt{a^2+b^2}}


错误4:不理解ans

ans不是“计算了几次”。

它最终表示:

第几项第一次超过上限。

这两个概念很接近,但不要混淆。


二十、最后把这道题压缩成一个“万能思维模板”🧠

以后遇到这种:

不断根据前面的数据生成新数据,直到满足某个条件

可以想成:

准备初始数据 ↓ 判断有没有结束 ↓ 生成新数据 ↓ 更新旧数据 ↓ 再判断 ↓ …… ↓ 满足结束条件 ↓ 输出答案

对应本题就是:

a、b ↓ b有没有超过U? ↓ 没有 ↓ t = √(a²+b²) ↓ a=b b=t ↓ 继续 ↓ b > U ↓ 输出第几项

🌟 一句话记住这道题

送给同学们一个非常好记的口诀:

“两个数字合体,开平方根;旧 b 变新 a,新数字变新 b;没超过就继续,超过了就停!”


需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询