#cspjmn6. CSP-J 2026 初赛模拟卷 6

CSP-J 2026 初赛模拟卷 6

一、单项选择题(共 15 题,每题 2 分,共计 30 分;每题有且仅有一个正确选项)

  1. 在计算机系统中,操作系统的主要作用是( )。 {{ select(1) }}
  • A. 将用高级语言编写的程序翻译成机器语言
  • B. 管理和控制计算机的硬件与软件资源
  • C. 进行科学计算
  • D. 防范计算机病毒
  1. 在 NOI Linux 中,使用 g++ 编译一个名为 main.cpp 的源文件,并指定生成的可执行文件名为 main,正确的命令是( )。 {{ select(2) }}
  • A. g++ -o main main.cpp
  • B. g++ main.cpp -o main
  • C. g++ main.cpp main
  • D. g++ main -o main.cpp
  1. 对序列 {5,2,4,6,1,3} 进行直接插入排序,在完成前 3 个元素 {5,2,4} 的排序后,序列的状态是( )。 {{ select(3) }}
  • A. {2,4,5,6,1,3}
  • B. {2,5,4,6,1,3}
  • C. {4,2,5,6,1,3}
  • D. {5,2,4,6,1,3}
  1. 对于变量 x=25,y=7,表达式 (x ^ y) & ~(x & y) 的结果是( )。 {{ select(4) }}
  • A. 25
  • B. 30
  • C. 0
  • D. 7
  1. 下列几种排序算法中,在最坏情况下( )的时间复杂度与其他三种不同。 {{ select(5) }}
  • A. 冒泡排序
  • B. 选择排序
  • C. 插入排序
  • D. 归并排序
  1. 十六进制数 0xDEAD 与二进制数 1101 1110 1010 1101 的关系是( )。 {{ select(6) }}
  • A. 前者比后者大 1
  • B. 后者比前者大 1
  • C. 两者相等
  • D. 前者是后者的两倍
  1. 对几乎已经排好序的数据(只有少数元素位置不对)进行排序,( )算法最快。 {{ select(7) }}
  • A. 快速排序
  • B. 插入排序
  • C. 归并排序
  • D. 选择排序
  1. 一个项目团队中,每个成员都与其他恰好 3 个成员有直接协作关系。如果团队有 12 人,那么协作关系总共有( )种。 {{ select(8) }}
  • A. 18
  • B. 36
  • C. 12
  • D. 4
  1. 一个栈的入栈序列为 1,2,3,4,5。出栈序列中,4 是第一个出栈的元素。出栈序列( )是不可能的。 {{ select(9) }}
  • A. 4,5,3,2,1
  • B. 4,3,5,2,1
  • C. 4,2,3,5,1
  • D. 4,1,2,3,5
  1. 从 1,2,3,...,10 中选出 4 个不同的数,使得其中任意两个数的差都不小于 2,不同的选法有( )种。 {{ select(10) }}
  • A. 35
  • B. 70
  • C. 84
  • D. 120
  1. 以下代码段的时间复杂度是( )。
for (int i = n; i > 0; i /= 2, cout<<endl) {
    for (int j = 0; j < i; j++) {
        cout << i * j << " ";
    }
}

{{ select(11) }}

  • A. O(n)O(n)
  • B. O(nlogn)O(n\log n)
  • C. O(n2)O(n^2)
  • D. O(logn)O(\log n)
  1. 对长度为 n 的有序数组进行二分查找,( )不是必须满足的条件。 {{ select(12) }}
  • A. 数组元素必须连续存储
  • B. 数组必须按关键字有序
  • C. 必须能够随机访问元素
  • D. 数据量 n 最好较大
  1. 一棵二叉树的前序遍历序列是 ABDECF,中序遍历序列是 DBEAFC,则其后序遍历序列是( )。 {{ select(13) }}
  • A. DEBFCA
  • B. DEBFAC
  • C. DBEFCA
  • D. DBECFA
  1. 循环队列容量为 10,front = 7,rear = 3,元素个数为( )。 {{ select(14) }}
  • A. 4
  • B. 5
  • C. 6
  • D. 7
  1. 使用邻接表存储图,拓扑排序的时间复杂度是( )。 {{ select(15) }}
  • A. O(V)O(V)
  • B. O(E)O(E)
  • C. O(V+E)O(V+E)
  • D. O(V2)O(V^2)

二、阅读程序(程序输入不超过数组或字符串定义的范围;判断题正确填 ✓,错误填 ✗;除特殊说明外,判断题每题 2 分,选择题每题 3 分,共计 40 分)

(1)

 1 #include <iostream>
 2 #include <vector>
 3 using namespace std;
 4
 5 int solve(int n) {
 6   int sum = 0;
 7   for (int i = 1; i <= n/2; i++)
 8     if (n % i == 0) sum += i;
 9   return sum;
10 }
11
12 int main() {
13   int n;
14   cin >> n;
15   int sum = solve(n);
16   if (sum == n) {
17     cout << "perfect_number" << endl;
18   } else if (sum > n) {
19     cout << "abundant_number" << endl;
20   } else {
21     cout << "deficient_number" << endl;
22   }
23   return 0;
24 }

判断题

  1. 函数 solve 计算的是 n 的所有因数之和。 {{ select(16) }}
  • A. 正确
  • B. 错误
  1. 如果 n 是素数,那么 solve 的返回值总是 1。 {{ select(17) }}
  • A. 正确
  • B. 错误
  1. 当 n=496 时,程序会输出 "perfect_number"。 {{ select(18) }}
  • A. 正确
  • B. 错误

选择题

  1. n 的取值范围为 [10,100] 时,第一个输出 "abundant_number" 的 n 是( )。 {{ select(19) }}
  • A. 10
  • B. 12
  • C. 28
  • D. 72
  1. n 的取值范围为 [1,1000] 时,关于完全数(perfect number),以下说法中正确的是( )。 {{ select(20) }}
  • A. 所有完全数都是奇数
  • B. 所有完全数都是偶数
  • C. 完全数可以是素数
  • D. 完全数的个数是无限的

(2)

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int N=10009;
 4
 5 int n, nums[N];
 6
 7 int solve() {
 8   int res = n;
 9   for (int i = 0; i < n; i++) {
10     res ^= i;
11     res ^= nums[i];
12   }
13   return res;
14 }
15
16 int main() {
17   cin >> n;
18   // 保证输入的 n 个数在 0..n 范围内,且互不相同
19   for (int i = 0; i < n; i++) cin >> nums[i];
20   cout << solve() << endl;
21   return 0;
22 }

判断题

  1. 若输入 5 1 2 3 4 5,则输出结果是 0。 {{ select(21) }}
  • A. 正确
  • B. 错误
  1. 本题输入 num 数组的数据可以是无序的。 {{ select(22) }}
  • A. 正确
  • B. 错误
  1. 程序功能是判断 n 个数是不是连续的,如果不是连续的,则输出其中缺失的数。 {{ select(23) }}
  • A. 正确
  • B. 错误

选择题

  1. (4 分)若输入 7 7 1 6 2 5 3 0,则输出结果是( )。 {{ select(24) }}
  • A. 0
  • B. 3
  • C. 4
  • D. 8
  1. (4 分)算法利用的最主要的性质是( )。 {{ select(25) }}
  • A. 异或的交换律和结合律
  • B. 异或的交换律和分配律
  • C. 异或的结合律和分配律
  • D. 异或的交换律和幂零性

(3)

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int N = 100009;
 4 const int INF = 1e8 - 1;
 5 int a[N];
 6
 7 int main() {
 8   int n, x;
 9   cin >> n >> x;
10   for (int i = 0; i < n; i++) cin >> a[i];
11   sort(a,a+n,less<int>());
12
13   int left = 0, right = n - 1, p = n;
14   while (left <= right) {
15     int mid = (left + right) / 2;
16     if (a[mid] > x) {
17       p = mid;
18       right = mid - 1;
19     } else {
20       left = mid + 1;
21     }
22   }
23   cout << p << " ";
24   if (p < n) cout << a[p] << endl;
25   else cout << INF << endl;
26   return 0;
27 }

判断题

  1. 该程序使用二分查找,找到第一个大于或等于 x 的元素的下标和数值。 {{ select(26) }}
  • A. 正确
  • B. 错误
  1. 当输入 7 8 0 9 2 7 8 7 6 时,程序输出为 "7 9"。 {{ select(27) }}
  • A. 正确
  • B. 错误
  1. 数组排序后,也可以使用 upper_bound(a,a+n,x)-a 得到 p 的数值。 {{ select(28) }}
  • A. 正确
  • B. 错误

选择题

  1. (4 分)当输入 8 7 3 4 4 5 5 6 6 7 时,程序输出为( )。 {{ select(29) }}
  • A. 7 7
  • B. 8 7
  • C. 8 9999999
  • D. 8 99999999
  1. (4 分)对于输入的 n 个数的序列,下列说法中正确的是( )。 {{ select(30) }}
  • A. 序列中的元素可以从大到小有序
  • B. 序列中的元素可以从小到大有序
  • C. 序列中的元素可以无序
  • D. 以上说法都正确

三、完善程序(单选题,每小题 3 分,共计 30 分)

(1)

汉诺塔问题:有三根柱子 A、B、C,其中 A 柱上叠放有 n 个大小不同的圆盘,按大小顺序从下到上排列(最大的在最下面,最小的在最上面)。目标是将所有圆盘从 A 柱移动到 C 柱,并遵循以下规则:每次只能移动一个圆盘;移动过程中,任何柱子上都不能出现大盘在小盘上方的情况;可以使用 B 柱作为辅助。请输出所有操作步骤(将圆盘从一根柱子移动到另一根柱子,如:A->B),并在最后统计总的移动次数。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4
 5 ll steps = 0;
 6
 7 void hanoi(int n, char A, char B, char C) {
 8   if (n == 1) {
 9     cout << A << "->" << C << endl;
10     ①
11   } else {
12     hanoi(n - 1, A, C, B);
13     ②
14     steps++;
15     ③
16   }
17 }
18
19 int main() {
20   int n;
21   cin >> n;
22   if (n <= 0) {
23     cout << 0 << endl;
24     ④
25   }
26   ⑤
27   cout << steps << endl;
28   return 0;
29 }
  1. ①处应填( )。 {{ select(31) }}
  • A. return;
  • B. steps=1;
  • C. steps++;
  • D. steps+=n;
  1. ②处应填( )。 {{ select(32) }}
  • A. cout << A << "->" << B << endl;
  • B. cout << A << "->" << C << endl;
  • C. cout << B << "->" << C << endl;
  • D. cout << C << "->" << B << endl;
  1. ③处应填( )。 {{ select(33) }}
  • A. hanoi(n - 1, A, B, C);
  • B. hanoi(n - 1, A, C, B);
  • C. hanoi(n - 1, B, A, C);
  • D. hanoi(n - 1, B, C, A);
  1. ④处应填( )。 {{ select(34) }}
  • A. break;
  • B. continue;
  • C. n=0;
  • D. return 0;
  1. ⑤处应填( )。 {{ select(35) }}
  • A. hanoi(1, 'A', 'B', 'C');
  • B. hanoi(n, 'A', 'B', 'C');
  • C. hanoi(1, 'A', 'C', 'B');
  • D. hanoi(n, 'A', 'C', 'B');

(2)

Prim 算法是一种用于求解加权无向连通图的最小生成树(MST)的贪心算法。它的基本思想是从图中任意一个顶点开始,逐步扩展生成树,每次选择一条连接生成树和其余顶点的权重最小的边,并将该边和对应的顶点加入生成树。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int N = 1009;
 5 const ll INF = 1e9;
 6 vector<int> to[N], w[N];
 7 int n, m;
 8 ll d[N]; // d[i]=i号顶点到当前 MST 的最小边权
 9 bool ok[N]; // ok[i]=i号顶点是否在当前 MST 中
10 void add(int u, int v, int k) {
11   to[u].push_back(v);
12   to[v].push_back(u);
13   w[u].push_back(k);
14   w[v].push_back(k);
15 }
16
17 ll Prim() {
18   ①
19   ll ans = 0;
20   d[1] = 0;
21
22   for (int k = 1; k <= n; k++) {
23     int u = ②;
24     for (int i = 1; i <= n; i++)
25       if (③) u = i;
26     ok[u] = 1;
27     ans += ④;
28
29     for (int i = 0; i < to[u].size(); i++) {
30       int v = to[u][i], cost = w[u][i];
31       if (⑤) d[v] = cost;
32     }
33   }
34   return ans;
35 }
36
37 int main() {
38   cin >> n >> m;
39   int u, v, k;
40   for (int i = 1; i <= m; i++) {
41     cin >> u >> v >> k;
42     add(u, v, k);
43   }
44   cout << Prim() << endl;
45   return 0;
46 }
  1. ①处应填( )。 {{ select(36) }}
  • A. fill(d, d + n + 1, -1);
  • B. fill(d, d + n + 1, INF);
  • C. fill(d, d + n + 2, -1);
  • D. fill(d, d + n + 2, INF);
  1. ②处应填( )。 {{ select(37) }}
  • A. -1
  • B. 0
  • C. n
  • D. n + 1
  1. ③处应填( )。 {{ select(38) }}
  • A. d[i] < d[u]
  • B. d[i] > d[u]
  • C. !ok[i] && d[i] < d[u]
  • D. ok[i] && d[i] < d[u]
  1. ④处应填( )。 {{ select(39) }}
  • A. u
  • B. d[u]
  • C. k
  • D. d[k]
  1. ⑤处应填( )。 {{ select(40) }}
  • A. !ok[v] && cost < d[v]
  • B. !ok[v] && cost > d[v]
  • C. ok[v] && cost < d[v]
  • D. ok[v] && cost > d[v]