2026 CSP-J 初赛真题及解析(第一轮·入门级)

四季读书网 8 0
2026 CSP-J 初赛真题及解析(第一轮·入门级)

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

int 32 位(约 ±2.1×10⁹)、float 有效数字约 7 位、double 约 15~16 位,都装不下 19 位的 10¹⁸+1。long long 64 位有符号整数(约 ±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 = 6a%b = 7%3 = 16+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] = {13579};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 < 2returnfalse;for (int i = 2; i * i <= x; i++)if (x % i == 0returnfalse;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,段数不变,更新最小/最大平均值。


四、参考答案速查表

题号
答案
题号
答案
题号
答案
1
B
16
31
B
2
D
17
×
32
D
3
C
18
33
C
4
C
19
A
34
D
5
B
20
C
35
B
6
D
21
C
36
D
7
D
22
37
B
8
C
23
×
38
C
9
B
24
×
39
B
10
A
25
B
40
D
11
A
26
A
41
C
12
D
27
C
42
A
13
C
28
×
43
D
14
A
29
15
B
30

本文基于 2026 年 CSP-J 第一轮认证真题整理,答案与解析仅供参考,最终以 CCF 官方发布为准。祝各位同学初赛顺利!

抱歉,评论功能暂时关闭!