下列代码的输出是( )。
#include <iostream>
using namespace std;
int main() {
int array[10];
for (int i = 0; i < 10; i++)
array[i] = i;
for (int p = 2; p < 10; p++)
if (array[p] == p)
for (int n = p; n < 10; n += p)
array[n] = array[n] / p * (p - 1);
int res = 0;
for (int n = 1; n < 10; n++)
res += array[n];
cout << res << endl;
return 0;
}这题本质是模拟素数筛选(埃拉托斯特尼筛法)的变体。拿到题先别急着跑代码,先在草稿纸上把数组初始化后的 0~9 写出来,然后顺着 p=2,3,5,7 这几个素数,一步步画内层循环怎么把它们的倍数改写。最后把 n=1 到 9 的数加一遍,答案自然出来。
最容易掉进两个坑:一是以为题目在算素数个数或求和,直接选 C 45(1~9 的和)或者 A 15(只处理了前几个数),忽略了数组元素已经被改成了 (p-1);二是内层循环步长 n+=p 理解错,把 p=2 时误以为只改奇数位置,或者忘记 p=3 时 array[6] 会被再次修改成 2,导致累加结果算错。
本题位于 GESP 三级大纲「数组与循环」模块,是三级试卷常考题型。命题人专门放这道题,就是要卡住那些只会看语法声明、完全不敢模拟执行的考生——他们往往以为数组操作就是「写几个循环」,却对循环嵌套的实际执行顺序毫无概念。
数组初始化后是 0~9。外层循环 p 从 2 到 9,条件 array[p] == p 实际就是筛选素数(2,3,5,7)。关键观察在于内层循环 n = p; n < 10; n += p 正好遍历 p 的倍数。通法是:素数筛选 + 倍数遍历,对每个倍数执行 array[n] = array[n] / p * (p - 1),即把原值除以 p 再乘 (p-1)。
1. 初始化:array = [0,1,2,3,4,5,6,7,8,9] 2. p=2:array[2]==2 成立。内层 n=2,4,6,8: - n=2: array[2] = 2/2*(1) = 1 - n=4: array[4] = 4/2*(1) = 2 - n=6: array[6] = 6/2*(1) = 3 - n=8: array[8] = 8/2*(1) = 4 此时 array = [0,1,1,3,2,5,3,7,4,9] 3. p=3:array[3]==3 成立。内层 n=3,6,9: - n=3: array[3] = 3/3*(2) = 2 - n=6: array[6] = 3/3*(2) = 2 - n=9: array[9] = 9/3*(2) = 6 此时 array = [0,1,1,2,2,5,2,7,4,6] 4. p=4:array[4]==2≠4,跳过 5. p=5:array[5]==5 成立。内层 n=5: - n=5: array[5] = 5/5*(4) = 4 此时 array = [0,1,1,2,2,4,2,7,4,6] 6. p=6:array[6]==2≠6,跳过 7. p=7:array[7]==7 成立。内层 n=7: - n=7: array[7] = 7/7*(6) = 6 此时 array = [0,1,1,2,2,4,2,6,4,6] 8. p=8,9 均不满足条件,结束。
res = 0 n=1: res += 1 → 1 n=2: res += 1 → 2 n=3: res += 2 → 4 n=4: res += 2 → 6 n=5: res += 4 → 10 n=6: res += 2 → 12 n=7: res += 6 → 18 n=8: res += 4 → 22 n=9: res += 6 → 28 输出 28,对应选项 B。
从数据看,2023-2026 年基础语法与控制结构考题量激增,循环控制类题目虽总数少但集中在 CSP 提高级和 GESP 一二级,说明这类「嵌套循环 + 条件筛选」的题型在未来高难度考试中仍会高频出现。暂无足够依据预测未来可能怎么考。