ARTICLE · 1040639
2026年CSP-J初赛试题和解析(附答案)
认证时间:2026-09-19 09:30–11:30 满分 100 分
以上题目来自竞赛家长圈等公众号整理而成
答案和答案由多篇资料整理,非官方标准答案,最终以官方试卷和答案为准。仅供学习参考。
第一部分 题目
一、单项选择题(共 15 题,每题 2 分,共 30 分)
【1】 下列 C++ 数据类型中,能够精确存储 1018+1 这个整数的是( )
A. float B. long long C. double D. int
【2】 十六进制数 2F5 转换为八进制数是( )
A. 1364 B. 1635 C. 1405 D. 1365
【3】 执行下列 C++ 代码,输出是( )int a = 7, b = 3;cout << a / b *b+ a % b;
A. 9 B. 10 C. 7 D. 6
【4】 初始栈为空,将 1、2、3、4 依次入栈,入栈过程中允许随时出栈。下列出栈序列中不可能出现的是( )
A. 2, 4, 3, 1 B. 3, 4, 2, 1 C. 1, 2, 3, 4 D. 1, 3, 2, 4
【5】 一棵有 100 个结点的完全二叉树,其叶子结点个数是( )
A. 49 B. 50 C. 64 D. 51
【6】 执行下列代码后 s 的值是( )int s = 0;for (int i = 1; i <= 100; i++) for (int j = 1; j <= i; j++) s += i + j;
A. 3048 B. 2733 C. 2318 D. 2418
【7】 上楼梯每步可上 1 级、2 级或 3 级,从地面(第 0 级)走到第 8 级台阶共有多少种不同走法( )
A. 120 B. 149 C. 156 D. 164
【8】 下图为 5×5 网格,行号、列号均从 0 开始,# 为障碍、· 为可通行格;

从 S 出发 BFS(按上、下、左、右顺序遍历相邻格),当 E 第一次入队时,已经入队过的格子有( )个。
A. 15 B. 14 C. 13 D. 12
【9】 满足 1 ≤ n ≤ 100,gcd(n, 60) = 6 的正整数 n 共有多少个( )
A. 8 B. 9 C. 6 D. 12
【10】 某国硬币面值为 1 元、4 元、6 元且数量不限,求出 9 元最少需要多少枚( )
A. 6 B. 4 C. 5 D. 3
【11】 执行下列代码,输出是( )int a[5]={1,4,14,7,13};int *p=a;*(p+1)=*(p+2)+*(p+3);cout<<a[1]<<" "<<a[2];
A. 14,13 B. 8,13 C. 14,7 D. 14,2
【12】 在包含 1000 个互不相同元素的升序数组中,用二分法查找给定值(返回元素位置或报告不存在),最坏情况下需要与数组元素比较多少次( )
A. 500 B. 9 C. 10 D. 11
【13】 数组 a[1..n] 的前缀和数组 s 满足 s[i]=3i²+i,则 a[10] 的值是( )
A. 252 B. 310 C. 381 D. 61
【14】 数轴上有 7 个点,坐标分别为 1, 3, 4, 7, 10, 15, 20,在数轴上选取一个整数坐标点 P,使 P 到这 7 个点的距离之和最小,这个最小距离和是( )
A. 37 B. 42 C. 40 D. 38
【15】 一个无向图有 10 个顶点,其中 4 个顶点的度为 3,其余顶点的度均为 4,则该图的边数是( )
A. 36 B. 18 C. 17 D. 20
二、阅读程序(判断题每题 1.5 分,选择题每题 3 分,共 40 分)
程序一
#include <iostream>using namespace std;int main() { int n; cin >> n; int x = 1, y = 1; while (n > 0) { if (n % 2 == 1) { x++; } else { y++; } n = n / 2; } cout << x << " " << y << endl; return 0;}
以下问题均假定输入的 n 为不超过\(2^{31}-1\)的非负整数。
【16】(判断(1分))当输入为 3 时,程序输出为 3 3。( )
【17】(判断)将第 11 行的 ++y 删除后,程序输出的两个数一定相等。( )
【18】(判断)假设输入为非负整数,则程序输出的第一个数一定不小于第二个数。( )
【19】(单选)将第 7 行的 while(n>0) 改为 while(n>=0) 后,程序可能出现的问题是( )A. 陷入死循环 B. 输出结果比原来大 C. 输出结果比原来小 D. 输出结果不受影响
【20】(单选)当输入为 6 时,输出为( )A. 3 3 B. 4 2 C. 4 3 D. 5 2
【21】(单选)若输入 n 依次取遍 0,1,2,…,2³¹−1 中的所有整数,则程序输出的第二个数恰好为 2 的次数为( )A. 16 B. 30 C. 31 D. 32
程序二
#include <algorithm>#include <iostream>#include <string>using namespace std;string a[100007], b[100007], c[100007], carry[100007];int a_len, b_len;int main() { string input_str; cin >> input_str; a_len = input_str.size(); for (int i = 0; i < a_len; i++) { a[i] = input_str[a_len - 1 - i] - '0'; } cin >> input_str; b_len = input_str.size(); for (int i = 0; i < b_len; i++) { b[i] = input_str[b_len - 1 - i] - '0'; } carry[0] = 0; for (int i = 0; i < max(a_len, b_len); i++) { c[i] = a[i] + b[i] + carry[i]; if (c[i] >= 10) { carry[i + 1] = 1; c[i] -= 10; } else { carry[i + 1] = 0; } } for (int i = max(a_len, b_len); i >= 0; i--) { cout << c[i]; } cout << endl; return 0;}
【22】(判断)当输入为 123 456 时,程序输出为 0579。( )
【23】(判断)假设输入的两个数均不含前导零,则程序输出的结果也一定不会含有前导零。( )
【24】(判断)将第 21 行改为 c[i+1]=a[i]+b[i] 后,程序输出的结果一定比原来的结果小。( )
【25】(单选)当输入为 12345 678 时,输出为( )A. 012923 B. 013023 C. 13023 D. 130230
【26】(单选)将 if(c[i]>=10) 改为 if(c[i]>10) 后,当输入为 95 15 时,输出为( )A. 01010 B. 1010 C. 140 D. 1410
【27】(单选)假设输入的两个数均为 10 位正整数(不含前导零),且它们的和小于 10¹⁰,则程序输出的字符串( )A. 第一个字符一定不为 '0' B. 长度一定等于 10 C. 长度一定为 n+1,且第一个字符为 '0' D. 长度可能为 n+2
程序三
#include <iostream>using namespace std;bool check_prime(int x) { if (x <= 1) return false; for (int i = 2; i * i <= x; i++) { if (x % i == 0) return false; } return true;}int n;void search_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); }}int main() { cin >> n; for (int i = 1; i <= 9; i++) { search_result(i); } return 0;}
【28】(判断)当输入为 10 时,程序的输出共有 10 行。( )
【29】(判断)若输入的 n 不大于 5,则程序的输出中一定包含 5。( )
【30】(判断)若输入的 n 大于 10,将第 17 行的 for 改为 for(...) 后,程序输出的结果一定不变。( )
【31】(单选)当输入为 24 时,程序输出的第 3 行为( )A. 23 B. 29 C. 31 D. 239
【32】(单选)下列关于该程序输出的说法中,正确的是( )A. 输出的数一定从小到大排列 B. 随着输入 n 增大输出数一定不会增加 C. 输出的数个位只可能是 3 或 7 D. 上述说法都不对
【33】(单选)当输入为 200 时,程序输出的行数为( )A. 12 B. 13 C. 14 D. 15
三、完善程序(每题 3 分,共 30 分)
(1)进制转换
给定 n、m,再给定一个 mn 进制下的数 A,其各个数位上的数按照从高位到低位的顺序给出。请你将其转化为 n 进制,并同样按照从高位到低位的顺序输出。
输入的第一行依次为 n、m 和 A 的位数 d,接下来 d 个数 ad, ad−1, …, a1 从高位到低位描述各个数位上的数。
数据满足 2 ≤ n, m ≤ 10,1 ≤ d ≤ 18,0 ≤ ai < mn。以下程序按「逐位除以 n」的方法完成进制转换。请补全程序。
#include <iostream>constexpr int N = 100005;long long b[N];int main() { long long n, m, d; std::cin >> n >> m >> d; for (int i = 0; i < d; i++) { long long x; std::cin >> x; for (int j = len - 1; j >= 1; j--) b[j] = ①; b[len] = ②; len++; for (int j = len; j >= 2; j++) { b[j - 1] += ③; b[j] = ④; if (j == len && b[j] == 0) len--; } } while ( ⑤ ) len--; for (int i = len - 1; i >= 0; i--) std::cout << b[i] << " "; return 0;}
第 34 题① 处应填( )
A. b[j] * n B. b[j] * m C. b[j−1] * n D. b[j−1] * m
第 35 题② 处应填( )
A. x * n B. x C. 0 D. m
第 36 题③ 处应填( )
A. b[j] / m B. b[j] % n C. b[j] % m D. b[j] / n
第 37 题④ 处应填( )
A. b[j] / m B. b[j] % n C. b[j] % m D. b[j] / n
第 38 题⑤ 处应填( )
A. len > 0 && b[len−1] == 0 B. len > 0 && b[0] == 0C. len > 1 && b[len−1] == 0 D. len > 1 && b[0] == 0
(2)平衡分割
给定一个长度为 n 的字符串,其中每个字符都是一个十六进制数位。例如,字符串 016A 表示十进制下的数 0, 1, 6, 10。
现在请选择 k 个(k 是你选定的数)划分位置 p1, p2, …, pk,其中 1 ≤ k < n,且 1 ≤ p1 < p2 < … < pk < n。再令 p0 = 0,pk+1 = n。
对于每个 0 ≤ i ≤ k,计算第 pi+1 个数到第 pi+1 个数的平均值,记作 bi。你的目标是使 b0, b1, …, bk 中最大值与最小值之差尽可能小,并输出这个最小值。
其中 2 ≤ n ≤ 20。输入字符串中的字符只可能是 0~9 或 A~F。本题假定字符采用 ASCII 编码。输出答案时保留小数点后 6 位。以下程序通过递归枚举所有可能的连续分段方案,请补全程序。
#include <algorithm>#include <iomanip>#include <iostream>#include <string>using namespace std;constexpr int N = 25;int n, a[N];char s[N];double ans = 1e100;double value(char c) { return ①; }void split(int l, int cnt, double minb, double maxb) { if (l == n) { if (cnt == 0) return; ans = min(ans, maxb - minb); return; } int sum = 0; for ( ② ) { sum += a[i]; double nwb = ③; split( ④ ); }}int main() { cin >> n >> s; for (int i = 1; i <= n; i++) a[i] = value(s[i]); split( ⑤ ); cout << fixed << setprecision(6) << ans; return 0;}
第 39 题① 处应填( )
A. isdigit(c) ? c−'0' : c−'A'+10 B. c−'A'+10C. c−'0' D. isdigit(c) ? c−'0' : c−'A'−10
第 40 题② 处应填( )
A. int i=l+1;i<=n;i++ B. int i=l;i<n;i++C. int i=l+1;i<n;i++ D. int i=l;i<=n;i++
第 41 题③ 处应填( )
A. sum/(i−l) B. 1.0*sum/(i−l+1)
C. sum/(i−l+1) D. 1.0*sum/(i−l)
第 42 题④ 处应填( )
A. split(i+1,cnt+1,min(minb,nwb),max(maxb,nwb))
B. split(i,cnt+1,min(minb,nwb),max(maxb,nwb))C. split(i+1,cnt,min(minb,nwb),max(maxb,nwb))
D. split(i,cnt,min(minb,nwb),max(maxb,nwb))
第 43 题⑤ 处应填( )
A. split(0,0,1e18,−1e18)
B. split(1,0,1e18,−1e18)
C. split(1,1,1e18,−1e18)
D. split(0,1,1e18,−1e18)
第二部分 参考答案与解析(仅供参考)
答案
一、单项选择题
1.B 2.D 3.C 4.C 5.B
6.D 7.D 8.C 9.B 10.A
11.A 12.D 13.C 14.A 15.B
二、程序阅读题
16. 对 17.错 18.对 19.A 20.C
21.C 22.对 23.错 24.错 25.B
26.A 27.C 28.错 29.对 30.对
31.B 32.D 33.C
三、完善程序题
34.D 35.B 36.D 37.B 38.C
39.B 40.D 41.C 42.A 43.D
完整解析
一、单项选择题解析
【1】 下列 C++ 数据类型中,能够精确存储 1018+1 这个整数的是( )
参考答案:B. long long
解析:1018+1 ≈ 1e18,超过 int 上限(≈2×109);float/double 为浮点,53 位尾数只能精确表示约 9×1015 以内的整数,无法精确存 1e18;long long 为 64 位有符号整数,上限 ≈9.2×1018,可精确存储。故选 B。
【2】 十六进制数 2F5 转换为八进制数是( )
参考答案:D. 1365
解析:2F516 = 2×16² + 15×16 + 5 = 512+240+5 = 75710。757 = 1×8³ + 3×8² + 6×8 + 5 = 13658。故选 D。
【3】 执行下列 C++ 代码,输出是( )int a = 7, b = 3;cout << a / b *b+a % b;
参考答案:C.7
解析:整数除法 7/3 = 2(向下取整),取模 7%3 = 1。
【4】 初始栈为空,将 1、2、3、4 依次入栈,入栈过程中允许随时出栈。下列出栈序列中不可能出现的是( )
参考答案:C
栈:后进先出 LIFO
要第一个弹出3,必须先依次压入1、2、3再弹出3,此时栈中自底向上为1、2,栈顶是2,只能先弹出2,无法先弹出1。
【5】 一棵有 100 个结点的完全二叉树,其叶子结点个数是( )
参考答案:B. 50
解析:完全二叉树中,有孩子的内部结点编号为 1…⌊n/2⌋,共 ⌊100/2⌋ = 50 个;叶子结点 = n − 内部 = 100 − 50 = 50(亦等于 ⌈n/2⌉)。故选 B。(注:此前草稿误作 51,此处更正为 50。)
【6】 执行下列代码后 s 的值是( )int s = 0;for (int i = 1; i <= 100; i++) for (int j = 1; j <= i; j++) s += i + j;
参考答案:D
解析:
3的倍数之和为1683,5的倍数之和为1050,15的倍数之和为315;容斥得1683+1050-315=2418。
【7】 上楼梯每步可上 1 级、2 级或 3 级,从地面(第 0 级)走到第 8 级台阶共有多少种不同走法( )
参考答案: B
解析:
设f(n)为走法数:f(1)=1,f(2)=2,f(3)=4,f(n)=f(n-1)+f(n-2)+f(n-3)。依次得f(4)=7、f(5)=13、f(6)=24、f(7)=44、f(8)=81。
【8】 下图为 5×5 网格,行号、列号均从 0 开始,# 为障碍、· 为可通行格;从 S 出发 BFS(按上、下、左、右顺序遍历相邻格),当 E 第一次入队时,已经入队过的格子有( )个。
参考答案:C
解析:
按上、下、左、右顺序BFS并标记已访问,依次入队:S(0,0)、(1,0)、(0,1)、(2,0)、(1,1)、(0,2)、(2,1)、(1,2)、(2,2)、(3,2)、(4.2)、(3,3)、(4,1),最后E(3,4)入队时恰为第14个。
【9】 满足 1 ≤ n ≤ 100,gcd(n, 60) = 6 的正整数 n 共有多少个( )
参考答案:B
解析:
gcd(n,60)=6要求n=6k且gcd(k,10)=1;由n≤100得k≤16,满足条件的k为1、3、7、9、11、13,共6个。
【10】 某国硬币面值为 1 元、4 元、6 元且数量不限,求出 9 元最少需要多少枚( )
参考答案:A
解析:
4+4+1只需3枚即可凑出9元;2枚最多12元但凑不出9元,故最少为3枚。注意6+1+1+1需要4枚,说明贪心取最大面额并不最优。
【11】 执行下列代码,输出是( )int a[5]={1,4,14,7,13};int *p=a;*(p+1)=*(p+2)+*(p+3);cout<<a[1]<<" "<<a[2];
参考答案:A
解析:
p指向a[2]:*(p-1)即a[1]=a[2]+a[4]=5+9=14;p[1]即a[3]=a[1]-a[0]=14-1= 13,输出14,13。
【12】 在包含 1000 个互不相同元素的升序数组中,用二分法查找给定值(返回元素位置或报告不存在),最坏情况下需要与数组元素比较多少次( )
参考答案:D
解析:二分查找每次把区间缩小一半,2^9=512<1000≤1024=2^10,最坏需要10次比较。。
【13】 数组 a[1..n] 的前缀和数组 s 满足 s[i]=3i²+i,则 a[10] 的值是( )
参考答案:C
解析:a[10]= s[10]- s[9]=(3x100+10)-(3x81+9)=310-252=58。
【14】 数轴上有 7 个点,坐标分别为 1, 3, 4, 7, 10, 15, 20,在数轴上选取一个整数坐标点 P,使 P 到这 7 个点的距离之和最小,这个最小距离和是( )
参考答案:A. 37
解析:距离和最小点取这 7 个数的中位数 P=7。和 = |1−7|+|3−7|+|4−7|+|7−7|+|10−7|+|15−7|+|20−7| = 6+4+3+0+3+8+13 = 37。故选 A。
【15】 一个无向图有 10 个顶点,其中 4 个顶点的度为 3,其余顶点的度均为 4,则该图的边数是( )
参考答案:B. 18
解析:度数总和 = 4×3 + 6×4 = 12 + 24 = 36;无向图边数 = 度数和 / 2 = 18。故选 B。
二、阅读程序解析
程序一(奇偶迭代)
【16】
参考答案:对
解析:
n=3时循环执行2次(3一1),x=1+2=3;过程中出现奇数3和1共2次,y=1+2=3,输出「33」,说法正确。
【17】
参考答案:错
解析:删去else中的++x后,x只统计偶数个数、y只统计奇数个数。n=3时序列3、1全为奇数,x=1、y=3,并不相等。
【18】
参考答案:对
解析:
x=1+n的二进制位数,y=1+n的二进制中1的个数,位数恒不小于1的个数,且n=0时两者都为1,故x恒不小于y。
【19】
参考答案:A.
解析:当 n 降到 0 后,while(0>=0) 仍成立,n%2==0 → y+=x,n/=2 仍为 0,永不退出,陷入死循环。故选 A。
【20】
参考答案:C
解析:
n=6时依次处理6(偶,x=2)、3(奇,x=3、y=2)、1(奇,x=4、y=3),随后n=0结束,输出[43」
【21】
参考答案:C
解析:
y=2等价于:n是2 的整数次幂(n=2^k)
n范围:0<=n<=2^(31-1)
2 的幂有:2^0=1, 2^1=2,2^2=4,....2^30)
一共:31个(指数从 0 到 30,共 31 个数)
n=0:循环不执行,输出 1 1,y=1,不算n=2^0=1, 2^1=2,...,2^30,共 31 个 n 满足输出第二个数y=2,答案等于31。
程序二(高精度加法)
【22】
参考答案:对
解析:123+456=579;输出从最高位i=max(3,3)=3打印到i=0,最高位补0,实际输出 0579,说法正确。
【23】
参考答案:错
解析:反例:12+34=46,两个加数都不含前导零,但程序从第2位开始输出,得到046,含有前导零。
【24】
参考答案:错
解析:
修改后不再累加低位进上来的carry。当各位相加都不满10时结果与原程序完全相同(如12+34两种情况都输出046),因此并非一定变小。
【25】
参考答案:B. 013023
解析:12345+678=13023。程序输出 max(5,3)+1=6 位并补前导零,得 “013023”。故选 B。
【26】
参考答案:A. 01010
解析:95+15=110。改后当 c[i]=10 时条件 10>10 为假,不进位、c[i] 保留 10。逐位:c[0]=5+5=10(不处理),c[1]=9+1+0=10(不处理),c[2]=0。逆序输出 6 位 “01010”。故选 A。
【27】
参考答案:C
解析:两 10 位数之和 < 10¹⁰,故和至多 10 位,无向第 11 位的进位。程序固定输出 max(len_a,len_b)+1 = 11 位,最高位 c[10]=0(前导零)。因此长度 = 11 = n+1 且首字符为 '0'(C 正确);A、B、D 均错误。若题目问“一定错误的是”,则 A/B/D 皆错,通常取 A(首项实为 '0')。
程序三
【28】
参考答案:错
解析:
n=10时输出为23、29、31、37、53、59,71、73、79,共9行,而不是10行。
【29】
参考答案:对
解析:5本身是质数,当n5时满足x≥n会被直接输出,且它的前缀链合法,故输出中一定包含5。。
【30】
参考答案:对
解析:
多位数若末位为偶数则不可能为质数,因此追加偶数数字的分支必然无法通过check prime,只会立即返回不产生任何输出,删去后结果不变。
【31】
参考答案:B
解析:n=24时输出顺序为233、239、29,31、37、....第3行为29。
【32】
参考答案:D
解析:
程序只在当前数已通过质数检查后才继续递归,所以输出的多位数删去末位后得到的前缀一定是质数;输出不按大小排序,n增大时行数会增加,个位还可能是1或9(如31、29)。
【33】
参考答案:C
解析:
n=200时输出的是所有[各位前缀均为质数」的三位质数:233、239、293、311、313、317、373、379、593、599、719、733、739、797,共14个;首位为1的链不会进入递归,故不存在四位数。
【34】
参考答案:C
解析:每读入一位前,先把已有的各位整体左移一位(权值乘m),即bj]=b[j-1]xm。
【35】
参考答案:B
解析:新的最低位就是当前读入的数位x,即b[0]=x。。
【36】
参考答案:D
解析:进位时向高一位累加除以n的商,即b[j+1]+=b[j/n。
【37】
参考答案:B
解析:本位保留除以n的余数,即bj]=bj]%n。
【38】
参考答案:C
解析:b[len-1]是最高位,需去掉最高位的0,同时至少保留一位,故条件为len>1&&b[len-1]==0。
三、完善程序
【39】
参考答案:B
解析:
此处将十六进制字符转换为对应数值。输入只包含10’~'9’和'A’~'F!,因此可以用c<'A判断是否为数字字符。
如果是数字字符,应计算c-'0';如果是字母,应计算c-'A!+10,也就是c-('A'-10)。故选B。A选项会把字符'9!错误地按字母处理。
【40】
参考答案:D
解析:
当前段从1开始,至少包含一个元素,因此右端点最小为1;当前段也可以一直延伸到序列末尾,因此右端点最大为n。为了枚举所有可能的分段位置,r每次增加1,故选D。A会漏掉长度为1的段,B无法让最后一段到达n,C会漏掉部分右端点。
【41】
参考答案:C
解析:
区间[l,r]共有r-1+1个元素,元素和为sum,所以平均值为sum/(r-1+
1)。由于平均值可能是小数,需要先乘1.0,再进行除法,故选C。
A先进行整数除法,小数部分已经丢失,之后再乘1.0也无法恢复;B的除数错误,且在r==1时会除以0;D错误地减去了当前段最后一个元素。
【42】
参考答案:A
解析:
当前段为[l,r],下一段应从r+1开始。
cnt|记录切分次数。只有r<n时,才需要在当前段与后面的元素之间切一刀。因此用cnt+(r<n)更新:条件成立时加1,否则加O。
加入当前段后,最小平均值更新为min(mnb,nwb),最大平均值更新为max(mxb,nwb),故选A。
B和D中的r<=n在循环中始终成立,会把最后一段也计为一次切分,使整串不切分的方案无法被cnt==0排除。C和D还交换了最大值、最小值的更新方式。
【43】
参考答案:D
解析:
输入使用cin >>n>>s+1,并将字符对应的数值存入a[1]~a[n],所以递归应从位置1开始。初始时尚未切分,cnt 为0。
为了正确维护最小值,mnb应初始化为极大值1e100;为了正确维护最大值,mxb 应初始化为极小值-1e100。这样加入第一段时,两者都会更新为第一段的平均值,故选D。