下面程序的输出为( )。
#include <iostream>
using namespace std;
int main() {
int N = 15, cnt = 0;
for (int x = 0; x + x + x <= N; x++)
for (int y = x; x + y + y <= N; y++)
for (int z = y; x + y + z <= N; z++)
cnt++;
cout << cnt << endl;
return 0;
}模拟程序执行过程,逐行跟踪变量变化,特别关注循环边界和递归终止条件。
模拟执行时注意:① 循环变量的起始和终止值;② 递归的边界条件;③ 数据类型转换和精度问题。
【考点】循环嵌套|组合计数|不等式约束
🎯 考纲定位:GESP 八级算法模块,重点考查"三重循环中的约束计数"能力。命题人把这道题放在这里,就是要卡住那些只会写循环、不懂数学本质、把"枚举"当成"暴力"的学生。
🧠 解题思维:看到三层循环,第一层 x 从 0 走到 N/3(因为 3x≤N),第二层 y 从 x 走到 (N−x)/2(因为 2y≤N−x),第三层 z 从 y 走到 N−x−y。cnt 最终等于满足 0≤x≤y≤z 且 x+y+z≤N 的整数三元组个数。这是经典的"有序整数分拆"问题,等价于把 N+3 个单位分成 3 个非负部分且保持顺序,可用组合公式 C(N+3,3)−C(N+2,2) 或递推求解。代入 N=15 得 174。
🪤 陷阱拆解:
最阴险的细节是第二层循环里 y 从 x 开始,而非 0,这直接让枚举空间减半,学生若不注意会漏掉一半计数。
🔄 反命题思维:如果把 N 改成 20,答案变成 286;如果把 x≤y≤z 放宽成 x≤y, y≤z 但允许相等(已是相等),或改成 x<y<z 严格递增,答案会少 45 个。再改成递归写法,本质仍是同一计数模型。刷到这类题时,先问自己:命题人想考我的是"循环边界"还是"组合计数"?——答案往往藏在约束的不等式里。