试卷解析 · 理解每一步
提高组 CSP-S 2026 初赛模拟卷 6
CSPS-2026-R1-Mock-6
试卷解析总览,可直接查看每题答案与解析。
第 1 题(单选题,2 分)
在以下各项中,( )不是 CPU 的组成部分。
正确答案D
解析详情
控制器、运算器、寄存器均为 CPU 的组成部分。主板是连接各元件的电路板。
第 2 题(单选题,2 分)
(2017) + (1234) 的结果是()。
正确答案B
解析详情
2017 转十进制为 , . 根据奇偶性排除选项 A 和 C, 再根据模 4 余 1 排除选项 D. 也可以逐个选项验证。
第 3 题(单选题,2 分)
设 , ,则下列逻辑运算表达式的值为假的是()。
正确答案D
解析详情
逐个代入验证即可。
第 4 题(单选题,2 分)
已知一个栈的入栈序列为 ,出栈序列为 ,若 ,则 。
正确答案C
解析详情
n 最后入栈,最先出栈,故出栈顺序为 。出栈顺序和入栈顺序相反,所以出栈的第 i 个元素就是从 n 开始倒着数的第 i 个元素,也就是 。
第 5 题(单选题,2 分)
设 ,其不同的非空子串有( )个。
正确答案A
解析详情
非空子串数量 ,子串 b 和 c 出现了 2 次,所以 21 - 2 = 19。
第 6 题(单选题,2 分)
在 C++ 中, 。
正确答案A
解析详情
125 = (1111101),异或2相当于二进制倒数第2位取反,这里就是加2,得127。
第 7 题(单选题,2 分)
设某算法的计算时间表示为递推关系式 (n 为正整数),且 ,则该算法的时间复杂度为()。
正确答案C
解析详情
根据主定理结论, , 。如不知道主定理,也可代入一个 n 估算,例如 n = 1024。
第 8 题(单选题,2 分)
下列有关二叉树的叙述(设根节点为第1层)中,不正确的是()。
正确答案C
解析详情
完全二叉树的最后一层不一定是满的,满二叉树是特殊的完全二叉树。
第 9 题(单选题,2 分)
下列排序算法中,平均时间复杂度是 的是()。
正确答案B
解析详情
插入排序是 ,其他是 。快速排序虽然最坏情况下的时间复杂度是 ,但这里问的是平均情况。
第 10 题(单选题,2 分)
下列图中一定可以进行黑白着色,使得相邻节点的颜色不同的是()。
正确答案A
解析详情
把树中深度为奇数的节点染成黑色,深度为偶数的节点染成白色即可。充要条件是二分图。树是一种特殊的二分图;基环树是二分图当且仅当唯一的环是偶阶环;选项 C 和 D 则与二分图没什么关联。
第 11 题(单选题,2 分)
下列不是操作系统的是()。
正确答案D
解析详情
WPS 是办公软件。
第 12 题(单选题,2 分)
下列关于算法的叙述中,错误的是()。
正确答案B
解析详情
衡量一个算法的好坏,性能方面至少包括时间复杂度和空间复杂度。广义上说还有可读性、容错性等更多参考指标。说“只需要考虑时间复杂度”显然是不对的。
第 13 题(单选题,2 分)
下列叙述中正确的是()。
正确答案A
解析详情
栈、队列是线性结构,树是非线性结构。
第 14 题(单选题,2 分)
链表的( )操作需要 时间复杂度的实现。
正确答案B
解析详情
链表的定位操作的时间复杂度是 ,因为没有全局下标访问功能,只有局部的前驱/后继功能。插入、删除、合并操作的时间复杂度是 。
第 15 题(单选题,2 分)
在 NOI 比赛中,不可以带入考场的是()。
正确答案C
解析详情
U 盘是必然不能带入的,笔可以带。纸张一般考场会发也不自带,但选项说的是空白纸张,相比之下还是 U 盘更明确。对于键盘则没有规定(也不可能有人自带键盘)。
二、阅读程序(1)
{1}
#include <iostream>
using namespace std;
int n, k, ans;
int main() {
cin >> n >> k; // 保证 n, k 是非负整数,且在 int 范围内
int ans = 0;
while (n) {
if (n % k > 0) ans++;
n /= k;
}
cout << ans << endl;
return 0;
}第 16 题(判断题,1 分)
把n%k>0改成n%k不影响程序运行结果。()
正确答案正确
解析详情
int 强制转为 bool,当且仅当非零时为 true,而这里 n%k 不可能为负数。
第 17 题(判断题,2 分)
输入的 k 需要大于 1,否则程序可能无法正常运行。 ()
正确答案正确
解析详情
k=0,则除数为0,k=1时,n/=k相当于没效果,会发生死循环。
第 18 题(判断题,2 分)
输入的 n 需要大于 0,否则程序可能无法正常运行。 ()
正确答案错误
解析详情
输入 n=0 时程序可以正常运行,输出 0。
第 19 题(判断题,2 分)
该算法的时间复杂度为 。 ()
正确答案正确
解析详情
n 在 k 进制意义下的位数严格说来是 ,但根据换底公式,底数只影响常数系数。
第 20 题(单选题,3 分)
输入 125 5 时,输出结果为()。
正确答案A
解析详情
。
第 21 题(单选题,3 分)
当 n 在 int 范围内时,输出的位数最大值为()。
正确答案C
解析详情
n 最大为 ,k=2 时输出 1 的位数最大为 31。
二、阅读程序(2)
#include <iostream>
using namespace std;
int equationCount(int n, int m) {
if (n == 1 || m == 1) return 1;
if (n < m) return equationCount(n, n);
if (n == m) return 1 + equationCount(n, n - 1);
return equationCount(n, m - 1) + equationCount(n - m, m);
}
int main() { // 本题不需要考虑数值溢出的可能性
int n;
cin >> n;
cout << equationCount(n, n) << endl;
return 0;
}第 22 题(判断题,1 分)
输入的 n 必须为正整数,否则程序无法正常运行。 ()
正确答案正确
解析详情
递归边界只有 n=m=1,而主函数调用又是 n,n。如果 n 是 0 或负数,递归时第 2 个参数 m 永远不会变大,也就不会达到 m==1,递归将陷入死循环而栈溢出。
第 23 题(判断题,2 分)
去掉 if (n == m) return 1 + equationCount(n, n-1); 这句,对输出无影响。()
正确答案错误
解析详情
不提前判断 n==m,这种情况就会调用 equationcount(n-m,m),导致参数 n 变成 0 从而陷入递归死循环。
第 24 题(判断题,2 分)
若主函数改为调用 equationCount(n, n+1),不影响程序运行结果。 ()
正确答案正确
解析详情
逻辑是 n 的正整数拆分中加数本来就不会超过 n;从该代码看第二个 if 还是会调用到 (n,n) 的情形(为避免有人硬说 引发 n+1 溢出,题目注释中特意说明了)。
第 25 题(判断题,2 分)
去掉 if (n < m) return equationCount(n, n); 这句,对输出无影响。 ( )
正确答案错误
解析详情
同第23题一样的原因。
第 26 题(单选题,3 分)
输入7时,输出结果为()。
正确答案D
解析详情
如果能看出逻辑含义,则直接手动算出 7 的拆分方案即可;或者利用递推式 推算。注意,手动推算用非递归方式更好,也就是按 n,m 从小到大计算。递归会有重复计算。
第 27 题(单选题,3 分)
该算法的时间复杂度为()。
正确答案D
解析详情
由于没有使用记忆法,递归实际上相当于把所有方案都枚举了一遍(最后的答案都是从 return 1 那个分支贡献的),所以复杂度呈指数级。如果使用记忆法,则复杂度为 。
另外,拆分数的最优解法可以做到 ,有两种做法:根号分治和五边形数定理。具体可自行调研。
二、阅读程序(3)
#include <iostream>
using namespace std;
const int maxn = 100000;
int a[maxn], b[maxn], n;
int Search(int num, int low, int high) {
int mid;
while (low <= high) {
mid = (low + high) / 2;
if (num >= b[mid]) low = mid + 1;
else high = mid - 1;
}
return low;
}
int main() {
int len, pos;
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
b[1] = a[1];
len = 1;
for (int i = 2; i <= n; i++) {
if (a[i] >= b[len]) b[++len] = a[i];
else {
pos = Search(a[i], 1, len);
b[pos] = a[i];
}
}
cout << len << endl;
return 0;
}第 28 题(判断题,2 分)
输入的 a[i] 必须在 [1,n] 范围内。 ()
正确答案错误
解析详情
a[i] 值并没有作为任何数组的下标,只参与赋值和比大小,所以可以是 int 范围内的任意数。
第 29 题(判断题,2 分)
把 if (num >= b[mid]) low = mid + 1; 中的 mid + 1 改成 mid, 不影响程序运行结果。()
正确答案错误
解析详情
因为 mid 是向下取整,所以如果改了,在 low+1=high 的情况下,就会出现 low=low 的赋值,造成死循环。
第 30 题(判断题,2 分)
当数组 a 单调不降时,输出为 1。()
正确答案错误
解析详情
输出为 n,如果看不出算法逻辑,代入 n=2,a={1,2} 进行模拟也能判定。
第 31 题(判断题,2 分)
数组 b 内的元素始终单调不降。 ()
正确答案正确
解析详情
a 数组大于 b 数组最后一位数,就把 a 增加到 b 数组;如果小于,就找到 b 数组中第一个大于等于 a[i] 的数替换掉。这个过程保持 b 数组单调不降(随便写组数据模拟一下这个过程就明白了)。
第 32 题(单选题,3 分)
若输入以下数据,则输出为()。
20
1 20 2 19 3 18 4 17 5 16 6 15 7 14 8 13 9 12 10 11
正确答案C
解析详情
该序列的最长不降子序列为 1 2 3 4 5 6 7 8 9 10 11,长度为 11。
第 33 题(单选题,3 分)
该算法的时间复杂度为()。
正确答案B
解析详情
二分查找的复杂度 ,外层还有一个 i=1..n 的循环。
三、完善程序(1)
(精准覆盖问题)给定一个 的 0-1 矩阵,求选出其中的一些行,使对 1..M 的每一列,在所选行内有且只有一行该列为 1。例如如下的矩阵中第 1、4、5 行就是一种可行解。
11100001 10001110 10010110 00010010 00001100
输入数据:有多组数据,每组数据第一行的两个整数为 N, M;接下来 N 行,每行开头为一个整数 x,表示该行 1 的个数,其后的 x 个整数表示每个 1 所在的列编号。
输出要求:如果有解,随意输出一组可行解的行的集合,否则输出 NO。
#include <bits/stdc++.h>
using namespace std;
#define inf 1000000000
#define N 2005
#define M 2000005
int n, m, h[N], s[N], q[N];
int u[M], d[M], L[M], R[M], C[M], X[M];
void del(int c) {
①;
②;
for (int i = d[c]; i != c; i = d[i])
for (int j = R[i]; j != i; j = R[j])
u[d[j]] = d[u[j]] = j, s[C[j]]--;
}
void add(int c) {
L[R[c]] = R[L[c]] = c;
for (int i = u[c]; i != c; i = u[i])
for (int j = L[i]; j != i; j = L[j])
u[d[j]] = d[u[j]] = j, s[C[j]]++;
}
bool dance(int k) {
if (R[0] == 0) return true;
int mn = inf, c;
for (int i = R[0]; i; i = R[i])
if (s[i] < mn) mn = s[i], c = i;
③;
for (int i = d[c]; i != c; i = d[i]) {
q[k + 1] = i;
for (int j = R[i]; j != i; j = R[j]) ④;
if (dance(k + 1)) return true;
for (int j = L[i]; j != i; j = L[j]) ⑤;
}
add(c);
return false;
}第 34 题(单选题,3 分)
①处应填()。
L[L[c]]=R[c];L[R[c]]=L[c];R[L[c]]=R[c];R[R[c]]=L[c];正确答案B(另接受:C)
解析详情
此题和下一题的选项完全相同,代码也在一起,所以其实是四选二。根据函数名,这里是要“删 c”,容易猜测 L 和 R 是左右相邻项。那么删 c 就是:c 前驱的后继改为 c 的后继(这样就跳过了 c),后继的前驱改为 c 的前驱。所以这两道题分别选 B 和 C。
第 35 题(单选题,3 分)
②处应填()。
L[L[c]]=R[c];L[R[c]]=L[c];R[L[c]]=R[c];R[R[c]]=L[c];正确答案C(另接受:B)
解析详情
同上。这两题的答案互换也是对的。
第 36 题(单选题,3 分)
③处应填()。
del(c);add(c);del(mn);add(mn);正确答案A
解析详情
dance(k) 是核心递归程序,就是枚举第 k 行选不选,③~⑤ 可以联合起来考虑。此题最简单的做法是根据 return 前的 add(c) 反向匹配,此处应是 del(c)。根据 del() 和 add() 中对 s 的操作,s 应该是表示某列的元素个数,而不是列编号,所以 mn 肯定是不对的,排除选项 C 和 D;而这里应该是选了这列,就要删掉,所以是 del()。
第 37 题(单选题,3 分)
④处应填()。
add(j);del(j);add(C[j]);del(C[j]);正确答案D
解析详情
最后这两题又是选项完全一样,当然此处答案不能互换,因为中间夹着一个递归调用。这两处明显应该是互逆的两次操作。再根据剪枝的逻辑,递归前应该是 del(),递归后是 add()。这里 C 是各列链表的头指针,这些头指针也组成一个列表,删整列就是在 C 这个头链表里删,所以选 D。
第 38 题(单选题,3 分)
⑤处应填()。
add(j);del(j);add(C[j]);del(C[j]);正确答案C
解析详情
见上题。
三、完善程序(2)
(树的直径)给定一棵有 n 个节点的树,每条边的长度为 。树的直径指树中最长的简单路径,请求这棵树的直径长度。
求解方法:开始任选一个节点 u 作为起点进行 BFS,找到距离 u 最远的节点 s;再以节点 s 为起点,再次进行 BFS,找到距离 s 最远的节点 t。s 和 t 之间的路径长度就是树的直径长度。
#include <iostream>
#include <cstring>
using namespace std;
const int inf = 0x3f3f3f3f;
const int maxn = 1005;
struct Node { int to, w, next; } edge[maxn * 2];
int head[maxn], tot, n, dis[maxn];
bool vis[maxn];
int que[maxn], first, last;
void init() {
memset(head, -1, sizeof(head));
tot = 0;
}
void addedge(int u, int v, int w) {
edge[tot].to = v;
edge[tot].w = w;
edge[tot].next = head[u];
head[u] = tot++;
}
int BFS(int u) {
first = last = 0;
memset(dis, inf, sizeof(dis));
memset(vis, 0, sizeof(vis));
dis[u] = 0;
vis[u] = 1;
que[last++] = u;
while (①) {
u = que[first++];
for (int i = head[u]; i != -1; i = edge[i].next) {
int v = edge[i].to;
if (②) {
vis[v] = 1;
que[last++] = v;
③;
}
}
}
int tmp = 1;
for (int i = 2; i <= n; i++)
if (④) tmp = i;
return tmp;
}
int main() {
int u, v, w, s, t;
cin >> n;
init();
for (int i = 1; i < n; i++) {
cin >> u >> v >> w;
addedge(u, v, w);
addedge(v, u, w);
}
s = BFS(1);
⑤;
cout << dis[t] << endl;
return 0;
}第 39 题(单选题,3 分)
①处应填()。
first < lastfirst <= lastfirst < last-1last == n正确答案A
解析详情
队列不为空。根据之前初始化队列的代码,约定为 last == first 为空。
第 40 题(单选题,3 分)
②处应填()。
!vis[v]vis[v]vis[u]dis[v]正确答案A
解析详情
BFS 入队条件是新的节点 v 未访问。
第 41 题(单选题,3 分)
③处应填( )。
dis[v] = dis[u] + 1;dis[v] = dis[u] + edge[i].w;dis[u] = dis[v] + 1;dis[u] = dis[v] + edge[i].w;正确答案B
解析详情
从 u 走到 v,更新的是 dis[v],要加上边权。
第 42 题(单选题,3 分)
④ 处应填()。
dis[i] < dis[tmp]dis[i] < tmpdis[i] > dis[tmp]dis[i] == tmp正确答案C
解析详情
打擂台,找到最大的 dis 的下标。
第 43 题(单选题,3 分)
⑤处应填( )。
t = BFS(1);t = BFS(t);s = BFS(t);t = BFS(s);正确答案A
解析详情
要找与 s 距离最远的节点 t。