GoHack 真题速览
2026 CSP-J 第一轮入门级 真题
完整题目 · 参考答案 · 简短点评

J组这套题从基础概念逐步过渡到程序阅读和代码补全:前15题侧重知识点与小计算,16—33题重在读懂程序真实行为,34—43题考查补全关键代码的能力。
一|单项选择
第1题
下列 C++ 数据类型中,能够精确存储 10¹⁸ + 1 这个整数的是( )。
A. float
B. long long
C. double
D. int
参考答案:B|long long
64 位 long long 的整数范围覆盖这个数;浮点类型不能保证逐个整数精确表示。
第2题
十六进制数 2F5 转换为八进制数是( )。
A. 1364
B. 1635
C. 1405
D. 1365
参考答案:D|1365
先转成二进制,再从右向左每三位一组,得到 1365₈。
第3题
执行下列 C++ 代码,输出是( )。int a = 7, b = 3;std::cout << a / b * b + a % b;
A. 9
B. 10
C. 7
D. 6
参考答案:C|7
整数除法先得 2,余数为 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|3,1,2,4
3 先出栈后,2 仍压在 1 上面,因此无法接着弹出 1。
第5题
一棵有 100 个结点的完全二叉树,其中叶子结点个数是( )。
A. 49
B. 50
C. 64
D. 51
参考答案:B|50
编号 51~100 的 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|2418
用容斥:3 的倍数和+5 的倍数和-15 的倍数和。
第7题
上楼梯每步可上 1 级、2 级或 3 级,从地面(可视为第 0 级)走到第 8 级台阶共有多少种不同走法( )。
A. 44
B. 121
C. 149
D. 81
参考答案:D|81
用 f(n)=f(n−1)+f(n−2)+f(n−3) 递推,得到 f(8)=81。
第8题
下图为 5×5 网格,行号、列号均从 0 开始,# 为障碍,. 为可通行格:S . . #
.. . . #
.. . . #
.# # . . E
. . . # .
从 S 出发做广度优先搜索(BFS):初始时把 S 入队;每次取出队首格子,按“上、下、左、右”的顺序遍历四个相邻格子,越界、障碍或已访问的格子跳过,其余格子标记为已访问并入队。当 E 第一次入队时,已经入队过的格子(含 S 和 E)共有多少个( )。
A. 15
B. 12
C. 14
D. 13
参考答案:C|14
严格按入队顺序模拟并在入队时标记访问,计入起点与终点共 14 格。
第9题
满足 1 ≤ n ≤ 100 且 gcd(n,60) = 6 的正整数 n 共有多少个( )。
A. 8
B. 6
C. 4
D. 5
参考答案:B|6
写成 n=6k,再筛选与 10 互质且满足范围的 k,共 6 个。
第10题
某国硬币面值为 1 元、4 元、6 元且数量不限,凑出 9 元最少需要多少枚( )。
A. 3
B. 4
C. 5
D. 2
参考答案:A|3
6+1+1+1 需 4 枚,而 4+4+1 只需 3 枚。
第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|14,13
先将 a[1] 改为 5+9=14,再用新值计算 a[3]=14−1=13。
第12题
在含 1000 个互不相同元素的升序数组中,用二分法查找给定值(返回元素位置或报告不存在),最坏情况下需要与数组元素比较多少次?( )
A. 500
B. 9
C. 11
D. 10
参考答案:D|10
每比较一次大致减半,最坏需 10 次。
第13题
数组 a[1..n] 的前缀和数组 s(即 s[i] = a[1]+a[2]+···+a[i])满足 s[i] = 3i²+i。则 a[10] 的值是( )。
A. 252
B. 310
C. 58
D. 61
参考答案:C|58
a[10]=s[10]−s[9]=58。
第14题
数轴上有 7 个点,坐标分别为 1、3、4、7、10、15、20。在数轴上选取一个整数坐标点 P,使 P 到这 7 个点的距离之和最小,这个最小距离和是( )。
A. 37
B. 42
C. 40
D. 38
参考答案:A|37
取中位数 7,距离和为 37。
第15题
一个无向图有 10 个顶点,其中 4 个顶点的度为 3,其余顶点的度均为 4,则该图的边数是( )。
A. 36
B. 18
C. 17
D. 20
参考答案:B|18
度数和为 4×3+6×4=36,每条边计两次,所以有 18 条边。
二|阅读程序
第16—21题共用二进制位统计程序;第22—27题共用高精度加法程序;第28—33题共用“质数前缀”递归程序。
第16—21题共用题面与程序
(1)以下问题均假定输入的 n 为不超过 2³¹−1 的非负整数。
#include <iostream>
using namespace std;
int main() {
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;
return 0;
}
第16题
16. 当输入为 3 时,程序输出为 3 3。( )
A. 正确
B. 错误
参考答案:正确(A)
二进制 3 为 11,两轮循环都增加 x 和 y,最终均为 3。
第17题
17. 将第 11 行的 ++x; 删除后,程序输出的两个数一定相等。( )
A. 正确
B. 错误
参考答案:错误(B)
输入 1 时即可得到两项不相等,故“一定相等”不成立。
第18题
18. 假设输入为非负整数,则程序输出的第一个数一定不小于第二个数。( )
A. 正确
B. 错误
参考答案:正确(A)
x 记录二进制位数加 1,y 记录 1 的个数加 1。
第19题
19. 将第 7 行的 while (n > 0) 改为 while (n >= 0) 后,程序可能出现的问题是( )。
A. 陷入死循环
B. 输出结果比原来大
C. 输出结果比原来小
D. 输出结果不受影响
参考答案:A|陷入死循环
n 变为 0 后仍满足条件且持续保持 0,循环无法结束。
第20题
20. 当输入为 6 时,输出为( )。
A. 3 3
B. 4 2
C. 4 3
D. 5 2
参考答案:C|4 3
6 的二进制为 110,共三位、其中两位为 1,所以输出 4 3。
第21题
21. 若输入 n 依次取遍 0,1,2,...,2³¹−1 中的所有整数,则程序输出的第二个数恰好为 2 的次数为( )。
A. 16
B. 30
C. 31
D. 32
参考答案:C|31
第二项为 2 说明二进制中恰有一个 1,共 31 种。
第22—27题共用题面与程序
(2)本题输入的两个数均为非负整数,位数不超过 100000,可能包含前导零。
#include <algorithm>
#include <iostream>
#include <string>
using namespace std;
int a[100007], b[100007], c[100007], carry[100007];
string input_str;
int a_len, b_len;
int main() {
cin >> input_str;
a_len = input_str.size();
for (int i = 0; i < a_len; i++) {
a[i] = input_str[a_len - i - 1] - '0';
}
cin >> input_str;
b_len = input_str.size();
for (int i = 0; i < b_len; i++) {
b[i] = input_str[b_len - i - 1] - '0';
}
carry[0] = 0;
for (int i = 0; i < max(a_len, b_len) + 1; 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题
22. 当输入为 123 456 时,程序输出为 0579。( )
A. 正确
B. 错误
参考答案:正确(A)
程序从最高预留位开始输出,未去掉前导零。
第23题
23. 假设输入的两个数均不含前导零,则程序输出的结果也一定不会含有前导零。( )
A. 正确
B. 错误
参考答案:错误(B)
输出固定包含最高预留位;不进位时这一位是 0。
第24题
24. 将第 21 行改为 c[i]=a[i]+b[i]; 后,程序输出的结果一定比原来的结果小。( )
A. 正确
B. 错误
参考答案:错误(B)
没有进位的输入不会变,故“一定更小”不成立。
第25题
25. 当输入为 12345 678 时,输出为( )。
A. 012923
B. 013023
C. 13023
D. 130230
参考答案:B|013023
两数相加为 13023,程序还会输出一个最高位的 0。
第26题
26. 将第 22 行的 if (c[i]>=10) 改为 if (c[i]>10) 后,当输入为 95 15 时,输出为( )。
A. 01010
B. 110
C. 140
D. 1410
参考答案:A|01010
和恰为 10 的数位不再进位,输出会出现两位数位值。
第27题
27. 假设输入的两个数均为 n 位正整数(不含前导零),且它们的和小于 10ⁿ,则程序输出的字符串一定满足( )。
A. 第一个字符一定不为 '0'
B. 长度一定为 n
C. 长度一定为 n+1,且第一个字符为 '0'
D. 长度可能为 n+2
参考答案:C|长度一定为 n+1,且第一个字符为 '0'
程序固定打印 n+1 位;最高预留位为 0。
第28—33题共用题面与程序
(3)阅读程序。
#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题
28. 当输入为 10 时,程序的输出共有 10 行。( )
A. 正确
B. 错误
参考答案:错误(B)
递归只沿质数前缀延伸,实际行数并非 10。
第29题
29. 若输入的 n 不大于 5,则程序的输出中一定包含 5。( )
A. 正确
B. 错误
参考答案:正确(A)
一位质数 5 达到输出门槛,会直接打印。
第30题
30. 若输入的 n 大于 10,将第 17 行的 for (int i=0;i<=9;i++) 改为 for (int i=1;i<=9;i+=2) 后,程序的输出结果一定不变。( )
A. 正确
B. 错误
参考答案:正确(A)
多位质数末位不可能为偶数,原来走向偶数末位的分支会被质数检查剪掉。
第31题
31. 当输入为 24 时,程序输出的第 3 行为( )。
A. 23
B. 29
C. 31
D. 239
参考答案:B|29
按递归与数字顺序跟踪质数前缀,第 3 行为 29。
第32题
32. 下列关于该程序输出的说法中,正确的是( )。
A. 输出的数一定按照从小到大的顺序排列
B. 随着输入 n 的增大,输出的行数一定不会增加
C. 输出的数的个位数字只可能是 3 或 7
D. 输出的每个大于等于 10 的数,十进制下删去它的末位数字后得到的数一定是质数
参考答案:D|输出的每个大于等于 10 的数,十进制下删去它的末位数字后得到的数一定是质数
每个多位输出都由质数前缀递归而来,删去末位仍为质数。
第33题
33. 当输入为 200 时,程序输出的行数为( )。
A. 12
B. 13
C. 14
D. 15
参考答案:C|14
按可延伸的质数前缀逐层枚举,输出 14 行。
三|完善程序
第34—38题补全进制转换程序;第39—43题补全十六进制字符串平衡分割程序。
第34—38题共用题面与程序
(1 进制减半)给定 n,m,再给定一个 mn 进制下的数 A(mn 表示 m×n),其各个数位上的数按照从高位到低位的顺序给出,请将其转化为 n 进制,并同样按从高位到低位的顺序输出。第一行输入 n、m 和 A 的位数 d,接下来 d 个数从高位到低位描述各数位。2≤n,m≤10,1≤d≤18,0≤A<2⁶³。以下程序按逐位除以 n 的方法完成进制转换。
#include <iostream>
constexpr int N = 100005;
long long b[N];
int main() {
long long n, m, d;
std::cin >> n >> m >> d;
int len = 1;
for (int i = 0; i < d; i++) {
long long x;
std::cin >> x;
for (int j = len; j >= 1; j--) b[j] = ____①____;
b[0] = ____②____;
len++;
for (int j = 0; j < len; j++)
if (b[j] >= n) {
b[j + 1] += ____③____;
b[j] = ____④____;
if (j + 1 == len) len++;
}
}
while (____⑤____) len--;
for (int i = len - 1; i >= 0; i--) std::cout << b[i] << ' ';
return 0;
}
第34题
34. ①处应填( )。
A. b[j] * n
B. b[j] * m
C. b[j - 1] * n
D. b[j - 1] * m
参考答案:D|b[j - 1] * m
原进制为 m×n,转成 n 进制后每加一位需要先将旧值乘 m。
第35题
35. ②处应填( )。
A. x * n
B. x
C. 0
D. m
参考答案:B|x
把数位 x 放在最低位,再进行向高位进位。
第36题
36. ③处应填( )。
A. b[j] / m
B. b[j] % n
C. b[j] % m
D. b[j] / n
参考答案:D|b[j] / n
n 进制进位量为当前数位整除 n 的商。
第37题
37. ④处应填( )。
A. b[j] / m
B. b[j] % n
C. b[j] % m
D. b[j] / n
参考答案:B|b[j] % n
当前数位对 n 取余即可。
第38题
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|len >1 && b[len - 1] == 0
最高位为零时可缩短长度,但至少保留一位。
第39—43题共用题面与程序
(2 平衡分割)给定长度为 n 的十六进制数字符串(2≤n≤20)。选择 k 个切分位置,1≤k<n,把字符串分成 k+1 个连续段。计算各段数位的平均值,求这些平均值中最大值与最小值之差的最小值。输出保留小数点后 6 位。程序通过递归枚举所有连续分段方案。
#include <algorithm>
#include <iomanip>
#include <iostream>
using namespace std;
constexpr int N = 25;
int n;
char s[N];
double ans = 1e100;
int get_val(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 += ____③____;
double nwb = ____④____;
split(____⑤____);
}
}
int main() {
cin >> n >> s + 1;
split(1, -1, 1e100, -1e100);
cout << fixed << setprecision(6) << ans;
return 0;
}
第39题
39. ①处应填( )。
A. c <= '9' ? c - '0' : c - 'A' + 10
B. c <= '9' ? c - '0' : c - 'A'
C. c <= '9' ? c - '0' + 1 : c - 'A' + 10
D. c <= '9' ? c - '0' : c - 'A' + 9
参考答案:A|c <= '9' ? c - '0' : c - 'A' + 10
数字字符减 '0';A~F 在减 'A' 后加 10。
第40题
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
参考答案:A|int r = l; r <= n; r++
右端点从当前左端点 l 一直枚举到 n。
第41题
41. ③处应填( )。
A. get_val(s[r])
B. get_val(s[r-1])
C. s[r-1]
D. s[r]
参考答案:A|get_val(s[r])
每次纳入当前右端点 s[r] 的十六进制数值。
第42题
42. ④处应填( )。
A. sum/(r-l+1)
B. 1.0*sum/(r-l+1)
C. 1.0*sum/(r-l)
D. sum*1.0/n
参考答案:B|1.0*sum/(r-l+1)
使用 1.0×sum 做浮点除法,分母为段长 r−l+1。
第43题
43. ⑤处应填( )。
A. r+1, cnt+1, min(minb,nwb), max(maxb,nwb)
B. r, cnt+1, minb, maxb
C. r+1, cnt, nwb, nwb
D. r, cnt, min(minb,nwb), max(maxb,nwb)
参考答案:A|r+1, cnt+1, min(minb,nwb), max(maxb,nwb)
下一段从 r+1 开始,段数加一,并更新当前最小、最大平均值。
给家长的一句提醒
答案仅供参考,核对完答案后,先看孩子在哪类题上连续失分:基础概念、程序跟踪,还是算法补全。具体分数与晋级结果仍以官方公布为准。