2026 CSP-J 初赛真题及解析(第一轮·入门级)
2026 年 CSP-J 第一轮认证真题来了!本文逐题整理单项选择题、阅读程序、完善程序三大题型的完整题目、答案与详细解析,覆盖 43 道小题,方便同学们考后复盘、考前模拟。
获取 2026 CSP-J 初赛真题及解析.pdf
请关注状元编程公众号,回复 2026csp-j
一、单项选择题(共 15 题,每题 2 分,共 30 分)
第 1 题:下列 C++ 数据类型中,能够精确存储 10¹⁸ + 1 这个整数的是( )。
A. float B. long long C. double D. int
答案:B
int32 位(约 ±2.1×10⁹)、float有效数字约 7 位、double约 15~16 位,都装不下 19 位的 10¹⁸+1。long long64 位有符号整数(约 ±9.2×10¹⁸)可精确存储。考点:C++ 数据类型范围与精度。
第 2 题:十六进制数 2F5 转换为八进制数是( )。
A. 1364 B. 1635 C. 1405 D. 1365
答案:D
2F5₁₆ = 2×256 + 15×16 + 5 = 757₁₀。757₁₀ = 1365₈(757 = 1×512+3×64+6×8+5)。
考点:进制转换。
第 3 题:执行 int a = 7, b = 3; cout << a / b * b + a % b;,输出是( )。
A. 9 B. 10 C. 7 D. 6
答案:C
a/b = 7/3 = 2(整数除法截断),2*3 = 6,a%b = 7%3 = 1,6+1 = 7。考点:整数除法与取模。
第 4 题:栈初始为空,将 1、2、3、4 依次入栈,入栈过程中允许随时出栈。下列出栈序列中不可能出现的是( )。
A. 2,4,3,1 B. 1,2,3,4 C. 3,1,2,4 D. 1,4,3,2
答案:C
C:要第一个出 3,则 1、2、3 依次入栈,3 出后栈顶是 2,下一个却要出 1,但 1 在 2 下面,无法先出。其余选项均可模拟。
考点:栈的出栈顺序合法性。
第 5 题:一棵有 100 个结点的完全二叉树,其中叶子结点个数是( )。
A. 49 B. 50 C. 64 D. 51
答案:B
完全二叉树叶子数 = n - ⌊n/2⌋ = 100 - 50 = 50。
考点:完全二叉树叶子结点计算。
第 6 题:执行下列代码后 s 的值是( )。
int s = 0;for (int i = 1; i <= 100; i++)if (i % 3 == 0 || i % 5 == 0) s += i;A. 3048 B. 2733 C. 2318 D. 2418
答案:D
3 的倍数和 = 3×(1+…+33) = 1683;5 的倍数和 = 5×(1+…+20) = 1050;15 的倍数和(重复) = 15×(1+…+6) = 315。容斥:1683 + 1050 - 315 = 2418。
考点:容斥原理、循环累加。
第 7 题:上楼梯每步可上 1、2 或 3 级,从地面(第 0 级)走到第 8 级共有多少种不同走法( )。
A. 44 B. 121 C. 149 D. 81
答案:D
递推 f(n)=f(n-1)+f(n-2)+f(n-3),f(0)=1, f(1)=1, f(2)=2。依次得 f(3)=4, f(4)=7, f(5)=13, f(6)=24, f(7)=44, f(8)=81。
考点:递推 / 三步爬楼梯。
第 8 题:下图为 5×5 网格(行号列号从 0 开始,# 为障碍,. 可通行):
S . . # .. . . # .. . . # .. . . . E. . . # .从 S 出发做 BFS(按上、下、左、右顺序遍历),当 E 第一次入队时,已入队的格子(含 S 和 E)共有( )。
A. 15 B. 12 C. 14 D. 13
答案:C
逐层 BFS 模拟:S(0,0) 出发,按层扩展,E(3,4) 在第 6 层入队,此时累计入队格子数为 14 个(含 S 和 E)。
考点:广度优先搜索(BFS)模拟。
第 9 题:满足 1≤n≤100 且 gcd(n, 60) = 6 的正整数 n 共有( )。
A. 8 B. 6 C. 4 D. 5
答案:B
设 n = 6k,则 gcd(6k, 60) = 6·gcd(k, 10) = 6,故 gcd(k, 10) = 1。由 6k ≤ 100 得 k ≤ 16。1~16 中与 10 互质的 k 为 1, 3, 7, 9, 11, 13,共 6 个(对应 n = 6, 18, 42, 54, 66, 78)。
考点:最大公约数、互质计数。
第 10 题:硬币面值 1 元、4 元、6 元且数量不限,凑出 9 元最少需要( )枚。
A. 3 B. 4 C. 5 D. 2
答案:A
4+4+1 = 9,仅 3 枚;6+1+1+1 = 9 需 4 枚。最少 3 枚。
考点:凑硬币 / 贪心与动态规划(注意 6+1+1+1 不是最优)。
第 11 题:执行下列代码,输出是( )。
int a[5] = {1, 3, 5, 7, 9};int *p = a + 2;*(p - 1) = p[0] + p[2];p[1] = *(a + 1) - a[0];cout << a[1] << "," << a[3];A. 14,13 B. 8,13 C. 14,7 D. 14,2
答案:A
p 指向 a[2]=5。
*(p-1)即 a[1],赋值为 p[0]+p[2] = a[2]+a[4] = 5+9 = 14;p[1]即 a[3],赋值为*(a+1)-a[0]= a[1]-a[0] = 14-1 = 13。输出 "14,13"。考点:指针运算、数组与指针的关系。
第 12 题:在含 1000 个互不相同元素的升序数组中二分查找,最坏情况下需要比较( )次。
A. 500 B. 9 C. 11 D. 10
答案:D
最坏比较次数 = ⌈log₂1000⌉ = 10(2¹⁰ = 1024 > 1000)。
考点:二分查找时间复杂度。
第 13 题:数组 a[1..n] 的前缀和 s 满足 s[i] = 3i² + i,则 a[10] 的值是( )。
A. 252 B. 310 C. 58 D. 61
答案:C
a[10] = s[10] - s[9] = (3×100+10) - (3×81+9) = 310 - 252 = 58。
考点:前缀和与差分。
第 14 题:数轴上 7 个点坐标 1、3、4、7、10、15、20。选整数点 P 使 P 到各点距离之和最小,最小距离和是( )。
A. 37 B. 42 C. 40 D. 38
答案:A
使距离和最小的点是中位数(第 4 小),即 7。距离和 = |7-1|+|7-3|+|7-4|+|7-7|+|7-10|+|7-15|+|7-20| = 6+4+3+0+3+8+13 = 37。
考点:中位数的绝对值距离最小化。
第 15 题:无向图有 10 个顶点,其中 4 个度为 3,其余度为 4,则该图的边数是( )。
A. 36 B. 18 C. 17 D. 20
答案:B
度数之和 = 4×3 + 6×4 = 36。边数 = 度数之和/2 = 18。
考点:握手定理。
二、阅读程序(3 大题,共 40 分)
阅读程序(一):进制减半模拟
#include<iostream>usingnamespace std;intmain(){int n; cin >> n;int x = 1, y = 1;while (n > 0) {if (n % 2 == 0) { ++x; } else { ++x; ++y; } n = n / 2; } cout << x << ' ' << y << endl;return0;}程序功能:每次把 n 除以 2。x 统计循环执行次数 +1(即二进制位数 +1),y 统计 n 为奇数的次数 +1(即二进制中 1 的个数 +1)。
第 16 题(判断):当输入为 3 时,程序输出为 "3 3"。( )
答案:√
3(11₂):n=3 奇数 → x=2,y=2;n=1 奇数 → x=3,y=3。输出 "3 3"。
第 17 题(判断):将第 11 行的 ++x; 删除后,程序输出的两个数一定相等。( )
答案:×
删除后偶数分支 x 增而 y 不变,两数不一定相等(如 n=2 时输出不等)。
第 18 题(判断):假设输入为非负整数,则程序输出的第一个数一定不小于第二个数。( )
答案:√
x = 二进制位数+1,y = 二进制 1 的个数+1,1 的个数不会超过总位数,故 x ≥ y 恒成立。
第 19 题(单选):将第 7 行的 while (n > 0) 改为 while (n >= 0) 后,程序可能出现的问题是( )。
A. 陷入死循环 B. 输出结果比原来大 C. 输出结果比原来小 D. 输出结果不受影响
答案:A
n=0 时 0%2=0,++x,n=0/2=0 恒为 0,永远无法退出,陷入死循环。
第 20 题(单选):当输入为 6 时,输出为( )。
A. 3 3 B. 4 2 C. 4 3 D. 5 2
答案:C
6(110₂):n=6 偶数 → x=2;n=3 奇数 → x=3,y=2;n=1 奇数 → x=4,y=3。输出 "4 3"。
第 21 题(单选):若输入 n 依次取遍 0 ~ 2³¹-1 的所有整数,则输出的第二个数恰好为 2 的次数为( )。
A. 16 B. 30 C. 31 D. 32
答案:C
第二个数 y = 二进制中 1 的个数 +1。y=2 表示二进制中恰有 1 个 1,即 2 的幂:2⁰, 2¹, …, 2³⁰,共 31 个。
阅读程序(二):高精度加法
#include<iostream>#include<string>usingnamespace std;intmain(){ string a_str, b_str; cin >> a_str >> b_str;int a[1000] = {0}, b[1000] = {0}, c[1000] = {0};int a_len = a_str.size(), b_len = b_str.size();for (int i = 0; i < a_len; i++) a[i] = a_str[a_len - 1 - i] - '0';for (int i = 0; i < b_len; i++) b[i] = b_str[b_len - 1 - i] - '0';int max_len = max(a_len, b_len);int carry[1000] = {0};for (int i = 0; i <= max_len; i++) { c[i] = a[i] + b[i] + carry[i];if (c[i] >= 10) { carry[i + 1] = 1; c[i] -= 10; } }for (int i = max_len; i >= 0; i--) cout << c[i];return0;}程序功能:字符串读入两个大整数,低位在前存入数组,逐位相加并处理进位,从高位到低位输出结果。
第 22 题(判断):当输入为 123 456 时,程序输出为 0579。( )
答案:√
123+456 = 579。循环到 max(3,3)+1 = 4 位,c[0]=9, c[1]=7, c[2]=5, c[3]=0,输出 "0579"。
第 23 题(判断):假设输入的两个数均不含前导零,则程序输出的结果也一定不会含有前导零。( )
答案:×
两数位数相同且无最高位进位时,最高位 c[max_len]=0,会输出前导零(如 111+222 输出 "0333")。
第 24 题(判断):将第 21 行改为 c[i] = a[i] + b[i]; 后,程序输出的结果一定比原来的结果小。( )
答案:×
去掉 carry 后进位信息丢失,结果不一定更小(如 5+5 原输出 "10",改动后数值仍为 10)。
第 25 题(单选):当输入为 12345 678 时,输出为( )。
A. 012923 B. 013023 C. 13023 D. 130230
答案:B
12345+678 = 13023,逐位进位后输出 "013023"。
第 26 题(单选):将第 22 行的 if (c[i] >= 10) 改为 if (c[i] > 10) 后,当输入为 95 15 时,输出为( )。
A. 01010 B. 110 C. 140 D. 1410
答案:A
95+15=110。改为
>10后,c[i]=10 时不进位不减 10:c[0]=10, c[1]=10, c[2]=0,输出 "01010"。
第 27 题(单选):假设输入的两个数均为 n 位正整数(不含前导零),且它们的和小于 10ⁿ,则程序输出的字符串一定满足( )。
A. 第一个字符一定不为 '0' B. 长度一定为 n C. 长度一定为 n+1,且第一个字符为 '0' D. 长度可能为 n+2
答案:C
和 < 10ⁿ 说明无最高位进位,循环到 n+1 位,c[n]=0,输出长度 n+1 且第一个字符为 '0'。
阅读程序(三):可截断质数搜索(DFS)
#include<iostream>usingnamespace std;int n;boolcheck_prime(int x){if (x < 2) returnfalse;for (int i = 2; i * i <= x; i++)if (x % i == 0) returnfalse;returntrue;}voidsearch_result(int x){if (!check_prime(x)) return;if (x >= n) { cout << x << endl;return; }for (int i = 0; i <= 9; i++)search_result(x * 10 + i);}intmain(){ cin >> n;for (int i = 1; i <= 9; i++) search_result(i);return0;}程序功能:输出所有 ≥n 的"可截断质数"——一个数本身是质数,且从右往左每次删去末位后得到的每个数都是质数。
第 28 题(判断):当输入为 10 时,程序的输出共有 10 行。( )
答案:×
n=10 时输出所有 ≥10 的可截断质数,共 9 行(23,29,31,37,53,59,71,73,79)。
第 29 题(判断):若输入的 n 不大于 5,则程序的输出中一定包含 5。( )
答案:√
n≤5 时,5 本身是质数且 5≥n,必被输出。
第 30 题(判断):若输入的 n 大于 10,将第 17 行的 for (int i=0; i<=9; i++) 改为 for (int i=1; i<=9; i+=2) 后,程序的输出结果一定不变。( )
答案:√
n>10 时输出的都是大于 10 的质数,其个位只能是 1、3、7、9,追加偶数或 5 不会产生新的可截断质数,故结果不变。
第 31 题(单选):当输入为 24 时,程序输出的第 3 行为( )。
A. 23 B. 29 C. 31 D. 239
答案:B
n=24 时 DFS 序:2 的分支先扩展,23<24 继续扩展出 233、239(第 1、2 行),再输出 29(第 3 行)。
第 32 题(单选):下列关于该程序输出的说法中,正确的是( )。
A. 输出的数一定按照从小到大的顺序排列 B. 随着输入 n 的增大,输出的行数一定不会增加 C. 输出的数的个位数字只可能是 3 或 7 D. 输出的每个大于等于 10 的数,十进制下删去它的末位数字后得到的数一定是质数
答案:D
D 正是"可截断质数"的定义。A 错(DFS 序非递增);B 错(n 增大行数减少);C 错(个位可为 1、9)。
第 33 题(单选):当输入为 200 时,程序输出的行数为( )。
A. 12 B. 13 C. 14 D. 15
答案:C
所有 ≥200 的可截断质数共 14 个,输出 14 行。
三、完善程序(2 大题,每题 5 空,共 30 分)
完善程序(一):m 进制转 n 进制
将 m 进制数转换为 n 进制数输出。
#include<iostream>#include<string>usingnamespace std;intmain(){ string s;int m, n; cin >> m >> n >> s;int b[1000] = {0};int len = 1;for (int i = 0; i < s.size(); i++) {int x = (s[i] >= '0' && s[i] <= '9') ? (s[i] - '0') : (s[i] - 'A' + 10);// ① 把已有结果整体乘以 mfor (int j = 0; j < len; j++) b[j] = ____①____;// ② 把新读入的一位数字 x 放入个位 b[0] = ____②____;// ③④ 规范化:按目标进制 n 处理进位for (int j = 0; j < len; j++) { b[j + 1] += ____③____; b[j] = ____④____; }while (b[len] > 0) len++; }// ⑤ 去除高位前导零while (____⑤____) len--;for (int i = len - 1; i >= 0; i--) cout << b[i];return0;}第 34 题:① 处应填( )。 A. b[j] * n B. b[j] * m C. b[j-1] * n D. b[j-1] * m → 答案:B
已有结果逐位乘以原进制基数 m。
第 35 题:② 处应填( )。 A. x * n B. x C. 0 D. m → 答案:B
将新一位数字 x 放入个位(b[0])。
第 36 题:③ 处应填( )。 A. b[j] / m B. b[j] % n C. b[j] % m D. b[j] / n → 答案:D
进位时,高位加上 b[j] 除以目标进制 n 的整数部分。
第 37 题:④ 处应填( )。 A. b[j] / m B. b[j] % n C. b[j] % m D. b[j] / n → 答案:B
进位后当前位保留 b[j] 对 n 取余的余数。
第 38 题:⑤ 处应填( )。 A. len > 0 && b[len-1] == 0 B. len > 0 && b[0] == 0 C. len > 1 && b[len-1] == 0 D. len > 1 && b[0] == 0 → 答案:C
去除最高位前导零:当最高位为 0 且长度大于 1 时缩短。
完善程序(二):平衡分割(递归枚举分段)
给定数字字符串,递归枚举所有分段方式,求各段平均值的最小值与最大值。
#include<iostream>#include<string>usingnamespace std;string s;int n;voiddfs(int l, int cnt, int minb, int maxb){int sum = 0;for (____②____) { sum += ____③____;int nwb = ____④____; // 当前段平均值 ____⑤____; // 递归处理下一段 }}第 39 题:① 处应填(将字符转数值)。 A. (c>='0'&&c<='9')?(c-'0'):(c-'A'+10) B. c - '0' C. c - 'A' D. (c>='0'&&c<='9')?(c-'0'):(c-'A') → 答案:B
输入的字符串只含数字字符 0~9,直接
c - '0'得到数值。
第 40 题:② 处应填(枚举当前段结束位置)。 A. int r=l; r<=n; r++ B. int r=l; r<n; r++ C. int r=1; r<=n; r++ D. int r=l; r++<n → 答案:D
r++ < n先判断后自增,循环体内 r 从 l+1 到 n,枚举当前段 [l, r]。
第 41 题:③ 处应填(累加当前段字符)。 A. get_val(s[r]) B. get_val(s[r-1]) C. s[r-1] D. s[r] → 答案:C
r 已在条件中自增,用 s[r-1] 取当前加入段的字符。
第 42 题:④ 处应填(当前段平均值)。 A. sum/(r-l+1) B. 1.0*sum/(r-l+1) C. 1.0*sum/(r-l) D. sum*1.0/n → 答案:A
用整数除法计算当前段 [l, r] 的平均值。
第 43 题:⑤ 处应填(递归下一段)。 A. dfs(r+1, cnt+1, min(minb,nwb), max(maxb,nwb)) B. dfs(r, cnt+1, minb, maxb) C. dfs(r+1, cnt, nwb, nwb) D. dfs(r, cnt, min(minb,nwb), max(maxb,nwb)) → 答案:D
起始位置为 r,段数不变,更新最小/最大平均值。
四、参考答案速查表
本文基于 2026 年 CSP-J 第一轮认证真题整理,答案与解析仅供参考,最终以 CCF 官方发布为准。祝各位同学初赛顺利!