ARTICLE · 1008076
2026年9月 GESP C++ 一级真题解析:把"读程序"练成条件反射
2026年9月 GESP C++ 一级真题解析:把"读程序"练成条件反射
一级整卷难度不高,但读程序写结果的题占了 11 道。一级考的不是知识点有多深,而是"你能不能准确模拟计算机执行"。
一、答案速查
判断题官方未公布答案,以下为按题意推算的参考答案(详见第四部分)。
二、单选题:四个模块,逐个击破
模块 1:计算机基础(第 1、2 题)
第 1 题 → C
四个选项都是 IDE 的常见功能,唯独"C. 可以直接控制机器人电机转动"越界了——IDE 只负责编写、编译、调试代码,真正控制电机的是编译后的程序加硬件驱动。
这道题在二级第 1 题原样又出了一遍。属于"送分题",但每年都有人错。
第 2 题 → D
计算机四个时代的划分依据是核心元器件:电子管 → 晶体管 → 中小规模集成电路 → 大规模/超大规模集成电路。
易错项是"运算速度"——速度是结果,元器件才是依据。
模块 2:表达式与运算符(第 3、4、6、7 题)
第 3 题 → A:int a = 4 + -2 * 3;先算乘法 -2 * 3 = -6,再算加法 4 + (-6) = -2。
第 4 题 → A:与 2 * -2 % 3 值相同的是 (2 * -2) % 3关键两点:① 乘号 * 与取余 %优先级相同,从左到右算;② C++ 中负数取余结果为负。
2 * -2 % 3 → (2 * -2) % 3 = -4 % 3 = -1B. 2 * (-2 % 3)=2 * (-2)= −4C. 2 * -(2 % 3)=2 * (-2)= −4D. 2 % -2 * 3=0 * 3= 0
第 6 题 → C:a = 8, b = 10
cout << (a % b) << ” ” << (a * 1 / b) << ” ” << (a * 1.0 / b);a % b= 8 % 10 = 8 a * 1 / b= 8 / 10 = 0(整数除法,直接截断) a * 1.0 / b= 8.0 / 10 = 0.8(出现浮点数即触发浮点除法)
输出 8 0 0.8。"整数除法截断"是一级最高频的失分点。
第 7 题 → D:int b = 8; ++b *= 2 + 1;先处理前缀自增:++b → b 变成 9;再算 2 + 1 = 3;最后 9 = 3 →27。(= 的右操作数是整个 2 + 1,不是 2。)
模块 3:循环与控制(第 8、9、10、11、13 题)
第 8 题 → A
for (i = 0; i < 10; i++) cnt += 1;cout << i << ' ' << cnt;
循环执行 10 次,cnt = 10;循环结束时 i 增到 10(不满足条件才退出)。输出 10 10。
第 9 题 → C
for (i = -10; i < 0; i++) cnt += 1; // cnt 最终 = 10cout << (i * cnt);
i 从 −10 到 −1,共 10 次;退出时 i = 0。所以 i * cnt = 0 * 10 =0。
第 10 题 → D
int i;for (i = 1; i < 5; i++) {if (i % 3 == 0) { printf(”%d+”, i); continue; }else { printf(”%d-”, i); break; }}printf(”%dEND*”, i);
i = 1: 1 % 3 != 0→ 走else,输出1-,break 直接终止整个循环,i保持 1;循环后输出 1END*。合起来是1-1END*,选 D。
第 11 题 → D(选"错误的")
int N, tot; cin >> N; tot = 0;while (N > 0) { cout << N << ”#”; tot += 1; N -= 1; }cout << tot << ”-END”;
程序会从 N 倒数打印到 1,最后输出循环次数 tot(等于 N)。
A:输入 3 → 3#2#1#3-END✔ 正确B:输入 −10 → 循环不执行, tot = 0→0-END✔ 正确C:输入 0 → 同理输出 0-END✔ 正确D:输入 1 → 实际是 1#1-END,而非1#0-END✘ 错误
第 13 题 → A
int k = 0;while (k < 8) { k += 2; continue; if (k > 5) break; cout << k << ”#”; }if (k >= 8) cout << ”FINISH”;
continue 让 cout 和 break永远不会被执行。k 依次为 2、4、6、8,到 8 时退出循环,输出 FINISH。
这是一道"死代码"题:读懂 continue 的位置,答案就一目了然。
模块 4:数位与"填空"题(第 12、14 题)
第 12 题 → B:"%3d", N - i输出样例每个数字占 3 列右对齐,且每 10 个换行。循环 i 从 0 到 N−1,每次应输出 N - i,所以填 "%3d", N - i。
第 14 题 → A:N / M10 % 10M10 = 10^(M-1),所以 N / M10 把要取的那一位挪到个位,再 % 10 取出来。
记牢这个万能模板:取从右往左第 M 位 =
N / 10^(M-1) % 10。
模块 5:鸡兔同笼改错(第 15 题)→ A
for (tu_tou = 0; tu_tou < tou + 1; tu_tou++) { // L1ji_tou = tou - tu_tou;if (tu_tou * 4 + ji_tou * 2 == jiao) { ...; break; }}if (tu_tou == tou) printf(”无解\n”); // L2
A 对:程序本身能正确求解。 B 错: ji_tou在循环体内马上被tou - tu_tou赋值,不需要额外初始化。C 错:把 tu_tou < tou + 1改成tu_tou < tou,会漏掉"全是兔子"(tu_tou = tou)的情况。D 错:无解时 tu_tou恰好停在tou,改成tou + 1则永远不输出"无解"。
三、判断题(10 题)
参考答案:√ × × √ √ √ √ × × ×
cin / scanf | ||
123 % 100 = 23 | ||
i = 21,输出 21 而非 20 | ||
10 > 10else,输出"10 小于 10" | ||
while (N > 0) { tot += N; N += -1; } | ||
2 % 2 = 0(-2) % 2 = 0,两数相同 | ||
z = 3.0 → z-- = 2.0 → cout << z++ | ||
___ 是两个不同的合法标识符,不会冲突 | ||
27 % 12 = 3double 得 3.0,结果确定 | ||
idx=5 被 continue,idx=7 触发 break) |
两道最容易做错的
第 8 题:不少人以为"下划线多了会混淆",其实 _、__、___都是独立合法的标识符。第 10 题: continue跳过的正是idx = 5那一次,所以 5 不加;idx = 7时7*7 = 49 > 30触发break。答案是 4,不是 3、也不是 8。
四、编程题
4.1 新龟兔赛跑
题意:距离固定为 1000。输入三行浮点数:乌龟全程用时 t1、兔子速度 v、兔子睡觉时长 t2。求谁赢,并输出兔子总用时(保留两位小数)。
解题思路
float t1, v, t2;cin >> t1 >> v >> t2;float tt = 1000.0 / v + t2; // 兔子:跑的时间 + 睡觉时间if (tt < t1) printf(”rabbit\n”);else if (tt > t1) printf(”turtle\n”);else printf(”tie\n”);printf(”%.2f\n”, tt);
三个关键点
浮点数比较必须写三种情况:小于、大于、等于(平局 tie)。漏掉tie就丢分。.0不能省:写 1000 / v会变成整数除法(若 v 为整数类型),必须写1000.0 / v。%.2f输出两位小数,不能用 cout默认输出(会丢掉末尾的 0,例如 21.0 而非 21.00)。
样例:20.0 / 100.0 / 11.0 → tt = 10 + 11 = 21.00 > 20 → 输出 turtle 和 21.00。
4.2 棋盘上的奖赏
题意:第 1 格 1 粒,以后每格翻倍(第 i 格 2^(i-1) 粒),求前 n 格总粒数。
核心公式
$$\text{总粒数} = 1 + 2 + 4 + \dots + 2^{n-1} = 2^{n} - 1$$
解法一:倍增累加(推荐,贴合考纲)
long long f = 1, ans = 0;for (int i = 1; i <= n; i++) {ans += f; // 累加当前格的麦粒f *= 2; // 每格翻倍}printf(”%lld\n”, ans);
解法二:位运算(更快,但要注意溢出)
ans = (1LL << n) - 1; // 注意 1LL,用 1 会溢出关键点
必须用 long long。n 稍大时2^n就会超过int范围(int最大约 2.1×10⁹,即2^31-1)。循环里先累加再翻倍,顺序不能反,否则会多算一格。 数据范围决定算法:n 到 30 左右,两种写法都行;n 到 60 以上,位运算写法更省事,但仍需 long long。
五、一级划重点
4 + -2 * 32 * -2 % 3 | |
8 / 10 = 08 * 1.0 / 10 = 0.8 | |
++b *= 2 + 1 | |
for (i = 0; i < 10; i++)i = 10 | |
continuebreak 的作用范围 | |
N / 10^(M-1) % 10 | |
%.2f |