夜雨聆风学习资料网

ARTICLE · 1042522

《CSP-J1 2026 真题+答案+详解:43 题完整版》

《CSP-J1 2026 真题+答案+详解:43 题完整版》

📌 本文导航

  • Part 0 答案速查表
  • Part 1 单选 1—15(题目+答案+解析)
  • Part 2 阅读程序 16—33(完整代码+逐题解析)
  • Part 3 完善程序 34—43(题干+代码+解析)

⚠️ 说明:最终以 CCF 官方发布为准。


Part 0|答案速查表

一、单项选择(每题 2 分)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
BDCCBDDCBAADCAB

二、阅读程序

16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
×
A
C
C
×
×
B
A
C
×
B
D
C

三、完善程序(每空 3 分)

34
35
36
37
38
39
40
41
42
43
D
B
D
B
C

Part 1|单项选择题(每题 2 分)

第 1 题

下列 C++ 数据类型中,能够精确存储 10¹⁸+1 这个整数的是( )

A. float B. long long C. double D. int

答案:B

解析:同时考"范围"和"精度"。

  • int 约 ±2.1×10⁹,存不下;
  • float 仅约 7 位有效数字,double 约 15—17 位,而 10¹⁸+1 有 19 位数字,个位的 1 会被舍入;
  • long long 范围 −9.22×10¹⁸ ~ 9.22×10¹⁸,且是整数类型,范围内整数 100% 精确。

第 2 题

十六进制数 2F5 转换为八进制数是( )

A. 1364 B. 1635 C. 1405 D. 1365

答案:D

解析:2F5(16) = 2×256 + 15×16 + 5 = 757;再除 8 取余:757→余5、94→余6、11→余3、1→余1,逆序读得 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/3=2,2×3=6,7%3=1,合计 7。记住恒等式 a = (a/b)×b + a%b。

第 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,必须已 push 1、2、3,此时栈顶是 2,下一个只能弹 2,不可能直接弹 1。C 非法。

第 5 题

一棵有 100 个结点的完全二叉树,其叶子结点个数是( )

A. 49 B. 50 C. 64 D. 51

答案:B

解析:n 个结点的完全二叉树,叶子 = ⌈n/2⌉。n=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

解析:容斥原理。

  • 3 的倍数和 = 3×(1+…+33) = 1683
  • 5 的倍数和 = 5×(1+…+20) = 1050(含 100)
  • 15 的倍数和(去重)= 15×(1+…+6) = 315
  • s = 1683 + 1050 − 315 = 2418

第 7 题

上楼梯每步可上 1 级、2 级或 3 级,从地面(第 0 级)走到第 8 级台阶共有多少种不同走法( )

A. 41 B. 165 C. 183 D. 81

答案:D

解析:递推 f(k) = f(k−1)+f(k−2)+f(k−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 出发做广度优先搜索(BFS):初始把 S 入队;每次取出队首格子,按"上、下、左、右"顺序遍历四个相邻格,越界、障碍或已访问格跳过,其余标记并入队。当 E 第一次入队时,已经入队过的格子(含 S、E)共有多少个( )

A. 15 B. 12 C. 14 D. 13

答案:C

解析:本题需对照原卷网格图(回忆版未完整保留图)。方法:在纸上画一张表,初始 S 入队并标记,反复取队首、按上下左右扩展入队,直到 E 入队为止,累计队中格子数。按原卷网格模拟结果为 14

第 9 题

满足 1 ≤ n ≤ 100 且 gcd(n, 60) = 6 的正整数 n 共有多少个( )

A. 3 B. 6 C. 4 D. 5

答案:B

解析:gcd(n,60)=6 ⟺ n=6k 且 gcd(k,10)=1。k=1…16 中与 10 互质(不被 2、5 整除)的是 1,3,7,9,11,13,共 6 个。

第 10 题

某国硬币面值为 1 元、4 元、6 元且数量不限,凑出 9 元最少需要多少枚( )

A. 3 B. 4 C. 5 D. 2

答案:A

解析:枚举验证:9 = 4+4+1 = 3 枚(最优);6+1+1+1 需 4 枚。

第 11 题

执行下列代码,输出是( )

int a[5] = {1, 3, 3, 2, 9};
int *p = &a[1];
*(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[i] = a[i+1]。关键:

  • 第一行 *(p-1) 改写的是 a[0];
  • 第二行右值里的 a[0] 是被改写后的值;
  • 按赋值先后逐行追踪数组,最终输出 a[1]、a[3] 为 14,13。 (本题以考场原卷代码为准。)

第 12 题

在含 1000 个互不相同元素的升序数组中,用二分法查找给定值,最坏情况下需要比较多少次( )

A. 500 B. 9 C. 11 D. 10

答案:D

解析:⌈log₂1000⌉ ≈ 10。1000→500→250→125→63→32→16→8→4→2→1,折 10 次。

第 13 题

数组 a[1…n] 的前缀和 s(即 s[i]=a[1]+…+a[i])满足 s[i] = 3i²+i,则 a[10] 的值是( )

A. 252 B. 310 C. 58 D. 61

答案:C

解析:a[i] = s[i] − s[i−1] = 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

解析:距离和最小点为中位数 P=7。距离和 = 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,边数 = 36/2 = 18


Part 2|阅读程序题(共 40 分)

卷面说明:判断题 1.5 分,正确填 √、错误填 ×;选择题 3 分。程序输入均合法。

程序一(16—21 题)

#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;
}

以下问题均假定输入 n 为不超过 2³¹−1 的非负整数。

读懂程序:循环把 n 不断除 2,就是转二进制的过程。

  • x 每轮都加 → x = 1 + 二进制位数
  • 只有最低位是 1 时 y 才加 → y = 1 + 二进制中 1 的个数

16. 当输入为 3 时,程序输出为 3 3。 答案:√

解析:3=(11)₂,位数 2 → x=3;1 的个数 2 → y=3。✓

17. 将第 11 行的 ++x 删除后,程序输出的两个数一定相等。 答案:×

解析:删掉后只有偶数位 x 才加,x=1+偶数位个数,与 y=1+1 的个数不再相等(如 n=8 时 x=4、y=2)。

18. 假设输入为非负整数,则程序输出的第一个数一定不小于第二个数。 答案:√

解析:位数 ≥ 1 的个数,故 x ≥ y;n=0 时两者都为 1。

19. 将 while(n>0) 改为 while(n>=0) 后,程序可能出现的问题是( )

A. 陷入死循环 B. 输出结果比原来大 C. 输出结果比原来小 D. 输出结果不受影响

答案:A

解析:n=0 后条件仍成立,而 0/2 永远是 0,死循环。

20. 当输入为 6 时,输出为( )

A. 3 3 B. 4 2 C. 4 3 D. 5 2

答案:C

解析:6=(110)₂,位数 3 → x=4;1 的个数 2 → y=3。

21. 若 n 取遍 0,1,2,…,2³¹−1,输出的第二个数恰好为 2 的次数为( )

A. 16 B. 30 C. 31 D. 32

答案:C

解析:y=2 即 1 的个数为 1,即 2 的幂 2⁰…2³⁰,共 31 个。


程序二(22—27 题)

#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 - 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) + 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;
}

本题输入两个非负整数,位数不超过 100000,可能含前导零。

读懂程序:标准高精度加法。关键细节:输出从 max(a_len,b_len) 开始倒打,不删前导零

22. 当输入为 123 456 时,程序输出为 0579。 答案:√

解析:和为 579,但从 i=3 开始打,最高位 c[3]=0 一并打出 → "0579"。✓

23. 假设输入的两个数均不含前导零,则输出也一定不含前导零。 答案:×

解析:如上例,无进位时最高位 c[max]=0 照样打印。

24. 将第 21 行改为 c[i]=a[i]+b[i] 后,输出结果一定比原来小。 答案:×

解析:只是丢了进位,无进位时结果完全相同,并非"一定小"。

25. 当输入为 12345 678 时,输出为( )

A. 012923 B. 013023 C. 19023 D. 130230

答案:B

解析:逐位加:个位 5+8=13→3 进1;十位 4+7+1=12→2 进1;百位 3+6+1=10→0 进1;千位 3;万位 1;最高位 0。从 i=5 倒打:013023

26. 将 if(c[i]>=10) 改为 if(c[i]>10),输入 95 15 时输出为( )

A. 01010 B. 110 C. 140 D. 1410

答案:A

解析:个位 5+5=10 不满足 >10,不减位;十位 9+1=10 同样不减。打印 c[2]=0、c[1]=10、c[0]=10 → 01010

27. 两数均为 n 位正整数(不含前导零),和小于 10ⁿ,则输出字符串一定满足( )

A. 第一个字符一定不为 '0' B. 长度一定为 n C. 长度一定为 n+1,且第一个字符为 '0' D. 长度可能为 n+2

答案:C

解析:和 < 10ⁿ 说明最高位无进位,c[n]=0;输出从 i=n 打 n+1 个字符,故长度 n+1、首位为 0。


程序三(28—33 题)

#include <iostream>
using namespace std;
bool check_prime(int x) {
if (x <= 1) returnfalse;
for (int i = 2; i * i <= x; i++)
if (x % i == 0) returnfalse;
returntrue;
}
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;
}

读懂程序:从 1—9 出发不断末尾拼数字,只要当前数仍是质数就继续,≥n 就输出。所有输出数去掉末位仍是质数

28. 当输入为 10 时,程序输出共有 10 行。 答案:×

解析:≥10 的有 23、29、31、37、53、59、71、73、79,共 9 行

29. 若 n 不大于 5,则输出中一定包含 5。 答案:√

解析:5 是质数且 5 ≥ n,search_result(5) 直接命中输出。

30. 若 n 大于 10,将 for(i=0;i<=9;i++) 改为 for(i=1;i<=9;i+=2) 后,输出结果一定不变。 答案:√

解析:被跳过的 i=0,2,4,6,8 拼出的数末尾是偶数、必非质数,进入即 return,本就不产生输出。

31. 当输入为 24 时,程序输出的第 3 行为( )

A. 23 B. 29 C. 31 D. 239

答案:B

解析:输出顺序 233(第1行)→ 239(第2行)→ 29(第3行)。

32. 下列关于该程序输出的说法,正确的是( )

A. 输出的数一定按从小到大排列 B. 随着 n 增大,输出行数一定不会增加 C. 输出的数个位只可能是 3 或 7 D. 每个 ≥10 的输出数,去掉末位后仍是质数

答案:D

解析:A 错(239 后又出 29);B 错;C 错(29、239 个位是 9);D 对,递归路径保证。

33. 当输入为 200 时,程序输出的行数为( )

A. 12 B. 13 C. 14 D. 15

答案:C

解析:≥200 的右截断质数共 14 个:233、239、293、311、313、317、373、379、593、599、719、733、739、797。


Part 3|完善程序题(每空 3 分,共 30 分)

第一题:m 进制转 n 进制(34—38)

题目:给定 n、m,再给定一个 m 进制下的数 A,各位从高位到低位给出,转化为 n 进制并同样高位到低位输出。第一行依次为 n、m 和位数 d,接下来 d 个数从高位到低位描述 A 的各位。2 ≤ n,m ≤ 10,1 ≤ d ≤ 18。程序按"逐位除以 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. ①处应填( )

A. b[j]*n B. b[j]*m C. b[j−1]*n D. b[j−1]*m

答案:D 现有数整体乘 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 除以 n 的商,进位到高位。

37. ④处应填( )

A. b[j]/m B. b[j]%n C. b[j]%m D. b[j]/n

答案:B 本位留余数(即 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 且至少剩一位时,去掉前导零。


第二题:字符串平衡分割(39—43)

题目:给定长度 n 的字符串,每位是十六进制数位(0—9、A—E)。选择 k 个分位置(1≤k<n),把字符串切成若干连续段;计算每段数值平均值 δ_i,使 δ 的最大值与最小值之差尽量小,输出该最小值,保留 6 位小数。2 ≤ n ≤ 20。以下程序通过递归枚举所有分段方案。

#include <algorithm>
#include <iomanip>
#include <iostream>
using namespace std;
constexpr int N = 25;
int n, a[N];
char s[N];
double ans = 1e100;

int value(char c) { return ① ____; }

void split(int l, int cnt, double mxb, double mnb) {
if (l > n) {
if (cnt == 0) return;
        ans = min(ans, mxb - mnb);
return;
    }
    int sum = 0;
for (② ____) {
        sum += a[x];
        double nwb = ③ ____;
        split(④ ____);
    }
}

int main() {
    cin >> n >> s + 1;
for (int i = 1; i <= n; i++) a[i] = value(s[i]);
    split(⑤ ____);
    cout << fixed << setprecision(6) << ans;
return 0;
}

39. ①处应填( )

A. c-(c<'9'?'0':'A'-10)B. c-(c<'A'?'0':'A'-10)C. c-(c<'A'?'A'-10:'0')D. c-(c<'A'?'0':'A'+10)

答案:B ⚠️ 数字字符 '0'~'9'都小于'A',返回 c−'0';字母返回 c−'A'+10。

40. ②处应填( )

A. int r = 1+1; r <= n; ++rB. int r = 1; r < n; ++rC. int r = 1; r <= n; r += 2D. int r = 1; r <= n; ++r

答案:D ⚠️ 枚举本段右端 r 从 l 到 n(含末尾)。

41. ③处应填( )

A. sum/(r-l+1)*1.0B. sum*1.0/(r-1)+1C. sum*1.0/(r-l+1)D. (sum-a[r])*1.0/(r-l+1)

答案:C ⚠️ 先乘 1.0 转浮点,再除以段长 r−l+1。

42. ④处应填( )

A. r+1, cnt+(r<n), min(mnb,nwb), max(mxb,nwb)B. r+1, cnt+(r<=n), min(mnb,nwb), max(mxb,nwb)C. r+1, cnt+(r<n), max(mnb,nwb), min(mxb,nwb)D. r+1, cnt+(r<=n), max(mnb,nwb), min(mxb,nwb)

答案:A  递归下一段:位置 r+1,后面还有段才 cnt+1,并用本段平均值更新全局最小/最大。

43. ⑤处应填( )

A. 0, 0, 1e100, -1e100B. 0, 0, -1e100, 1e100C. 1, 0, -1e100, 1e100D. 1, 0, 1e100, -1e100

答案:D  从位置 1 开始、分段数 0、最小值初值 +∞、最大值初值 −∞。


写在最后|考后三步

  1. 按 Part 0 估分:1—38 题三方核对可放心;39—43 谨慎对。
  2. 按本文复盘:重点吃透三段阅读程序(二进制统计、高精度加法、右截断质数),都是经典模型。
  3. 等晋级线:各省划线不同,以 CCF 官方公告为准。

点「在看」+「收藏」,这份完整真题+解析随时能翻出来给孩子复盘;关注本号,复赛(预计 10 月中下旬)攻略第一时间推送。

评论区聊聊:对完答案,你家孩子估了多少分?

#CSP #信息学奥赛 #CSP-J #初赛真题 #答案解析


相关学习资料