CSP-J 2026 初赛试题解析(第一部分:选择题(8-15))精讲



第 8 题:BFS 广度优先搜索------水波扩散

题目考查: 从起点 S 出发进行 BFS,每次按照"上、下、左、右"的顺序检查相邻格子。当终点 E 第一次入队时,已经入队过多少个格子?

选项:

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


🧙 故事:迷宫里的水波探险

想象我们把一滴水滴在迷宫的起点 S 上。

水波会先扩散到离起点最近的格子,再扩散到更远的格子。这就是 BFS(广度优先搜索)的特点:

一层一层向外探索,先探索近处,再探索远处。


BFS 通常使用队列 queue

  • 新发现的格子入队;

  • 每次取出队首格子进行探索;

  • 越界、障碍格子和已经访问过的格子都跳过。


🔍 本题的关键细节

题目特别规定了检查顺序:

复制代码
上、下、左、右

而且问的是:

E 第一次入队时,已经入队过多少个格子?

这里要特别注意:E 一入队就应该停止计数,不必等到 E 出队。

按照题目给出的地图和顺序模拟,直到 E 入队时,计数为 14


✅ 正确答案:C. 14


🌟 小学生记忆法

把 BFS 想成排队买票:

  1. 新发现的格子排到队伍后面;

  2. 每次从队伍最前面取出一个格子;

  3. 按规定顺序寻找新的格子;

  4. 题目问"入队多少个",就数被放进队伍的格子,而不是只数已经取出来的格子。

常见陷阱: 把"入队"误认为"出队",或者忘记按照题目规定的邻居顺序探索。



第 9 题:最大公约数 gcd

题目:

满足

的正整数 n 有多少个?

选项:

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


🧙 故事:寻找共同的因子伙伴

gcd(a,b) 表示 ab 的最大公约数,也就是同时能够整除这两个数的最大正整数。

题目要求:

首先,最大公约数是 6,说明 n 必须是 6 的倍数。

所以可以设:

n = 6 * k

由于 n 不超过 100:

6* k ≤ 100

因此:


🔍 进一步筛选

因为:

所以:

要让最大公约数恰好等于 6,就必须满足:

也就是说,k 不能与 10 有大于 1 的公因数。由于 10 的质因数是 2 和 5,k 不能是 2 的倍数,也不能是 5 的倍数。

在 1 到 16 中符合条件的 k 是:

1, 3, 7, 9, 11, 13

一共有 6 个。

对应的 n 是:

6, 18, 42, 54, 66, 78

✅ 正确答案:B. 6


🌟 记忆方法

遇到:

可以先想一想:

  1. n 是否一定是 d 的倍数?

  2. n=d×k 后,k 还需要满足什么条件?

  3. 最后根据范围枚举筛选。



第 10 题:硬币问题------怎样用最少的硬币凑出 9 元?

题目:

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

选项:

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


🧙 故事:硬币商店的购物挑战

我们有三种硬币:

复制代码
1 元、4 元、6 元

要凑出 9 元,并且硬币数量越少越好。

可以先尝试较大的硬币:

  • 用一枚 6 元硬币,还差 3 元,只能再用三枚 1 元硬币,一共 4 枚;

  • 用两枚 4 元硬币,已经有 8 元,还差 1 元,再用一枚 1 元硬币,一共 3 枚。

于是找到了一种 3 枚硬币的方案:

4+4+1=9


🔍 为什么不能只用 2 枚?

两枚硬币的组合只有这些可能:

  • 1+1=2

  • 1+4=5

  • 1+6=7

  • 4+4=8

  • 4+6=10

  • 6+6=12

没有任何一种组合恰好等于 9。

因此,2 枚不够,而 3 枚可以做到。

✅ 正确答案:A. 3


🌟 算法小提醒

这类问题看起来像是"尽量先用大硬币",但不能不加证明就认为贪心策略一定正确

对于本题,我们通过检查组合,证明了 3 枚可行、2 枚不可能,所以最少就是 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[0] a[1] a[2] a[3] a[4]
初始值 1 3 5 7 9

指针 p 指向数组中的某个位置:

复制代码
int *p = a + 2;

a + 2 表示指向 a[2],所以:

复制代码
p 指向 a[2],值为 5

第一步:执行 *(p - 1) = p[0] + p[2];

因为 p 指向 a[2]

  • p[0] 就是 a[2],值为 5;

  • p[2] 就是 a[4],值为 9;

  • p - 1 指向 a[1]

因此:

a1 = 5+9 = 14

数组变成:

下标 a[0] a[1] a[2] a[3] a[4]
当前值 1 14 5 7 9

第二步:执行 p[1] = *(a + 1) - a[0];

注意,第一步已经改变了 a[1]

所以:

  • *(a + 1) 就是 a[1],现在值为 14;

  • a[0] 的值是 1;

  • p[1] 就是 a[3]

于是:

a3 = 14−1 = 13

数组变成:

下标 a[0] a[1] a[2] a[3] a[4]
最终值 1 14 5 13 9

最后输出:

复制代码
cout << a[1] << "," << a[3];

得到:

复制代码
14,13

✅ 正确答案:A. 14,13


🌟 指针记忆卡

p 指向 a[k] 时:

复制代码
p[0]  == a[k]
p[1]  == a[k + 1]
p[-1] == a[k - 1]

还要记住:代码是按顺序执行的,前面修改了数组,后面的表达式就会使用修改后的值。



第 12 题:二分查找------每次砍掉一半

题目:

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

选项:

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


🧙 故事:猜数字游戏

老师心里想了一个数,它藏在从小到大排列的 1000 个数字里。

如果从第一个数字开始一个一个找,最坏可能要找 1000 次。

但二分查找有一个厉害的本领:

每次看中间的数字,就能排除大约一半不可能的范围。

例如:

复制代码
1000 个候选
    ↓
  约 500 个
    ↓
  约 250 个
    ↓
  约 125 个
    ↓
     ...

每比较一次,搜索范围就缩小一半左右。


🔍 计算比较次数

因为:

2^9=512

而:

1000 个元素的二分查找,最坏情况下需要 10 次比较。

✅ 正确答案:D. 10


🌟 复杂度记忆

二分查找的时间复杂度是:

O(log⁡n)

注意:二分查找要求数据已经按照适当的顺序排列;本题明确给出了升序数组。



第 13 题:前缀和------从累计总数中找出单独一项

题目:

数组 a[1..n] 的前缀和数组 s 满足:

a[10]

选项:

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


🧙 故事:累计收集宝石

前缀和 s[i] 表示从第 1 项一直加到第 i 项的总和:

例如:

s5 = a1+a2+a3+a4+a5s5

那么,想单独找出第 10 项怎么办?

可以用:

因为 s[10]s[9] 多出来的,恰好就是 a[10]

第一步:计算 s[10]

s10 = 300+10 = 310

第二步:计算 s[9]

s9 = 243 + 9= 252

第三步:相减

a10 = 310−252 = 58

✅ 正确答案:C. 58


🌟 记忆口诀

前缀和是大账本,

想找一项做减法:

当前总和减前项,

剩下的就是它!



第 14 题:数轴上的距离和------中位数的妙用

题目:

数轴上有 7 个点,坐标分别为:

1, 3, 4, 7, 10, 15, 20

选择一个整数坐标点 P,使 P 到这 7 个点的距离之和最小。最小距离和是多少?

选项:

A. 37  B. 42  C. 40  D. 38


🧙 故事:七位朋友约在哪里见面?

七位朋友住在数轴上的不同位置:

复制代码
1,3,4,7,10,15,20

大家想选一个整数位置集合,让所有人走过来的距离总和最小。

这时可以使用一个数学规律:

一组数到某个位置的绝对距离之和,在中位数位置取得最小值。


第一步:找到中位数

这些坐标已经从小到大排列。

一共有 7 个数,中间第 4 个数就是中位数:

P=7


第二步:计算距离之和

每个点到 7 的距离:

坐标 到 7 的距离
1 6
3 4
4 3
7 0
10 3
15 8
20 13

把它们加起来:

6+4+3+0+3+8+13 = 37

✅ 正确答案:A. 37


🌟 记忆口诀

数轴上要聚一聚,

距离总和想最小;

排序后找中位数,

再把距离加一起。



第 15 题:无向图的度数与边数

题目:

一个无向图有 10 个顶点,其中 4 个顶点的度为 3,其余顶点的度均为 4。该图的边数是多少?

选项:

A. 36  B. 18  C. 17  D. 20


🧙 故事:顶点的握手大会

把图中的每个顶点想象成一位同学。

如果两个顶点之间有一条边,就表示这两位同学握了一次手。

一个顶点的,就是与它相连的边的数量。

无向图有一个非常重要的规律:

所有顶点的度数之和,等于边数的 2 倍。


为什么呢?

因为每条边连接两个顶点,在统计度数时,这条边会被计算两次------两端各一次。

第一步:计算所有顶点的度数之和

4 个顶点的度为 3:

4×3=12

剩下:

10−4=6

个顶点的度为 4:

6×4=24

度数总和:

12+24=36

第二步:计算边数

设边数为 E

2E=36

所以:

E=18

✅ 正确答案:B. 18


🌟 图论记忆卡

对于无向图:

边数 = 所有顶点度数之和 / 2

这条规律常被称为握手定理


🎯 第 8---15 题考点汇总

题号 正确选项 核心知识点
8 C. 14 BFS、队列、入队顺序
9 B. 6 最大公约数、因数筛选
10 A. 3 硬币组合、最少数量
11 A. 14,13 指针与数组、按顺序模拟
12 D. 10 二分查找、对数复杂度
13 C. 58 前缀和、相邻前缀和相减
14 A. 37 中位数、绝对距离和
15 B. 18 无向图度数、握手定理

🏆 给同学们的提醒

题目中,有几类题目特别适合用"画图"和"模拟"来解决:

  • BFS 题: 画出队列变化,严格遵守题目给出的搜索顺序。

  • 指针题: 先画出数组下标,再一步一步修改数组,千万别跳步。

  • 二分查找题: 记住每次缩小一半的特点。

  • 前缀和题: 想找单独一项,就用相邻的前缀和相减。

  • 图论题: 无向图每条边连接两个顶点,所以度数总和要除以 2。

做选择题时,不要只想着"我好像见过这道题",而要问自己:

题目给了什么条件?要我求什么?我能用哪个规律把它们连接起来?

能把这三个问题想清楚,你就基本已经成功了。🌟


相关推荐
wabs6661 小时前
关于二叉树【力扣572.另一棵树的子树的思考】
数据结构·c++·算法·leetcode·二叉树
风合星语3 小时前
2026 ROS 2 Lyrical C++ 入门(五):Action 实战——任务反馈、取消与超时处理
c++·机器人·ros2·异步编程·lyrical
91刘仁德3 小时前
C++ 继承和多态 设计模式
c语言·c++·笔记
库玛西4 小时前
哈夫曼树与前缀编码:数据压缩的贪心核心
c语言·c++·笔记·考研
别动我齐刘海4 小时前
ROS2 Jazzy + C++ 实战路线——进阶学习3
c++·人工智能·vscode·python·算法·机器学习·机器人
0+1114 小时前
算法 --滑动窗口
c++·算法·leetcode
stolentime4 小时前
(有原题)CSP-S2026第一轮试题(附答案解析、markdown源码)
c++·csp
m0_734571764 小时前
深入理解C++ RAII
开发语言·c++
hetao17338375 小时前
2026-09-18 hetao1733837 的刷题记录
c++·算法