下面程序的输出为( )。
#include <iostream>
using namespace std;
int main() {
const int N = 30;
int cnt = 0;
for (int a = 1; a <= N; a++)
for (int b = a; a + b <= N; b++)
for (int c = b; a + b + c <= N; c++)
if (a * a + b * b == c * c)
cnt++;
cout << cnt << endl;
return 0;
}这道题考的是勾股数枚举与三重循环剪枝。拿到题先别急着套公式,把三个循环的上下界和 a²+b²=c² 这个条件翻译成具体的搜索范围,一层层推下去就能数出来。
最容易栽跟头的就是误以为勾股数很多,把 (9,12,15) 这种非本原的也算进去,或者把 a<b<c 的约束搞错导致多算。还有人在算 a+b+c≤30 时,没注意到 c 的下限是 b,导致 c 的取值范围写大了。另外,有人会用勾股数生成公式直接列数,却忘了题目给的 N=30 刚好把某些组合卡在外面,只靠公式背答案容易掉坑。
【考点】勾股数|带约束的三重循环|枚举计数
GESP 八级“数论与算法”模块,命题人想考的是“勾股数”概念与“带约束的三重循环枚举”的结合,卡住那些只背结论不会把不等式转化为搜索范围的考生。