#10624. 提高组CSP-S2025初赛模拟卷7
提高组CSP-S2025初赛模拟卷7
提高组 CSP-S 2025 初赛模拟卷 7
一、单项选择题(共 15 题,每题 2 分,共计 30 分;每题有且仅有一个正确选项)
- 在 NOI Linux 系统终端的调试工具 GDB 的使用中,以下( )命令可以用来查看某个变量的值,并一直显示直到关闭或者程序结束。
{{ select(1) }}
- printf
- show
- display
- 以下关于数据结构的表述中不恰当的一项是( )。
{{ select(2) }}
- 并查集常用森林来表示
- AVL 树插入破坏平衡的情况只有两种类型——LR 和 RL
- 线段树维护的常见区间信息包括区间最大值、区间最小值、区间相等
- 树状数组是主要用于前缀信息维护的一维数组
- 在 C++语言中,以下( )函数声明是合法的。
{{ select(3) }}
- int InsertSort(char a[], int n);
- int InsertSort(char a[10]], int n);
- int InsertSort(char a[][]20], int n);
- int InsertSort(char[,] a, int n);
- 对于给定的代码,调用 fun(5,6)得到的结果是( )。
{{ select(4) }}
- 210
- 126
- 252
- 240
- 二项展开式()的系数正好满足杨辉三角的规律,二项展开式中 项的系数是( )。
{{ select(5) }}
- 5
- 9
- 10
- 8
- 以下不属于 TCP/IP 协议族中网络协议的是( )。
{{ select(6) }}
- IMAP
- HTML
- TELNET
- UDP
- 构建具有 n 个元素的笛卡儿树的时间复杂度是( )。
{{ select(7) }}
- 考虑对 n 个数进行排序,以下方法中最坏情况下时间复杂度最差的排序方法是( )。
{{ select(8) }}
- 桶排序
- 快速排序
- 堆排序
- 归并排序
- 下面关于序列 的说法中正确的是( )。
{{ select(9) }}
- 是它的唯一最长连续下降子序列
- 是它的唯一最长连续上升子序列
- 是它的唯一最长上升子序列
- 是它的唯一最长下降子序列
- 给定地址区间为 0~13 的哈希表,哈希函数为 ,采用线性探查的冲突解决策略(如果出现冲突情况,会往后探查第一个空的地址存储;若地址 13 冲突了,则从地址 0 重新开始探查)。哈希表初始为空表,依次存储 后,请问 78 存储在哈希表的哪个地址中?( )
{{ select(10) }}
- 1
- 2
- 3
- 4
- 对于一个无向连通图 G,顶点之间的强连通关系不具有( )。
{{ select(11) }}
- 传递性
- 自反性
- 对称性
- 偏序性
- 以下 C++程序运行后的输出结果为( )。
{{ select(12) }}
- 84
- 90
- 91
- 96
- 下面的程序使用出边的邻接表表示有向图,则下列选项中哪个是它表示的图?( )

{{ select(13) }}
- 从不超过 30 的质数中随机抽取 2 个质数组成质数对 ,其中 ,则这 2 个质数组成的质数对中满足 的概率为( )。
{{ select(14) }}
- 2/15
- 17/30
- 11/15
- 7/12
- 在 4×4 方格表中,将若干格子染成黑色,每行每列恰有两个黑色格子的染色方法数为( )。
{{ select(15) }}
- 90
- 72
- 84
- 96
二、阅读程序(程序输入不超过数组或字符串定义的范围;判断题正确填√,错误填×;除特殊说明外,判断题每题 1.5 分,选择题每题 3 分,共计 40 分)
(1)
01 #include <bits/stdc++.h>
02 using namespace std;
03 const int N=3e5+10;
04 int n,k;char temp;
05 bool a[N];int dp[N];
06 int sum1[N];int sum2[N];
07 int Stack[N];int head=1;int tail=0;
08 int main() {
09 scanf("%d%d",&n,&k);
10 getchar();
11 for(int i=1;i<=n;i++) {
12 temp=getchar();
13 if(temp=='H')a[i]=0,sum1[i]+t;
14 else a[i]=1,sum2[i]+t;
15 sum1[i]+=sum1[i-1];sum2[i]+=sum2[i-1];
16 }
17 Stack[++tail]=0;
18 for(int i=1;i<=n;i++) {
19 while(head<=tail&&i=Stack[head]>)++head;
20 dp[i]=dp[Stack[head]]+(sum1[i]-sum2[i]) <=(sum1[Stack[head]]-sum2[Stack[head]]));
21 while(head<=tail&&((dp[i]*dp[Stack[tail]])) || (dp[i]==dp[Stack[tail]]
22 &&(sum1[i]-sum2[i])<=(sum1[Stack[tail]]-sum2[Stack[tail]])))
23 tail--;
24 Stack[++tail]=i;
25 }
26 printf("%d",dp[n]);
27 return 0;
28 }
假设输入满足 ,s 的长度为 n 且只含有 'H' 和 'G'。
判断题
- 这段代码的时间复杂度为 。
{{ select(16) }}
- √
- ×
- 代码运行到第 20 行时,head 永远小于 tail。
{{ select(17) }}
- √
- ×
- 删除第 10 行代码,程序运行结果可能改变。
{{ select(18) }}
- √
- ×
选择题
- 若程序输入
5 2
GGHGG
则程序的输出是( )。
{{ select(19) }}
- 0
- 1
- 2
- 3
- 若程序输入
7 2
HGHGGHG
则程序的输出是( )。
{{ select(20) }}
- 1
- 2
- 3
- 4
- 程序运行到最后一行时,以下哪个选项不成立?( )
{{ select(21) }}
- sum1[n]+sum2[n] == n
- tail-head <= n
- stack[1] = 0
- dp[n] 不一定是 dp 数组中的最小值
(2)
01 #include <bits/stdc++.h>
02 #define int long long
03 using namespace std;
04 int n,a[1000010],b[1000010],now,ans,front,N=1000000,c[3000010],id;
05
06 int lowbit(int x){return x6-x;}
07
08 void update(int x,int v){
09 x+=N;
10 for(int i=x;i<=n+N;i+=lowbit(i)) c[i]+=v;
11 }
12
13 int sum(int x) {
14 x+=N;
15 int ans=0;
16 for(int i=x;i;i-=lowbit(i)) ans+=c[i];
17 return ans;
18 }
19
20 signed main() {
21 ios::sync_with_stdio(0);
22 cin.tie(0),cout.tie(0);
23 cin>>n;
24 for(int i=0;i<n;i++) {
25 cin>>a[i];
26 b[i]=a[i]-(i+1);
27 now+=abs(b[i]);
28 update(b[i],1);
29 }
30 ans=now,id=0;
31 for(int i=i;i<n;i++) {
32 front=(front-1+n)%n;
33 b[front]--i-1;
34 now--abs(b[front]);
35 update(b[front],-1);
36 b[front]+=n-1;
37 now+=abs(b[front]);
38 int x=sum(0);
39 update(b[front],1);
40 N++;
41 now+=x*2-n+1;
42 if(ans>now) ans=now,id=i;
43 }
44 cout<<ans<<" "<<id;
45 return 0;
46 }
假设输入的是一个长度为 的排列,并且 。
判断题(每题2分)
- lowbit(114514)的结果是2。
{{ select(22) }}
- √
- ×
- 当 时,程序输出的 ans 值为6。
{{ select(23) }}
- √
- ×
- 第32行代码 front=(front-1+n)%n 可以改成 front=(front)%n-1。
{{ select(24) }}
- √
- ×
选择题
- 第35行中 update(b[front],-1)的作用是( )。
{{ select(25) }}
- 将 [1,b[front]] 的元素都减去1
- 将 (b[front],n] 的元素都减去1
- 将 b[front] 位置的元素减去1
- 以上说法都不对
- 若程序输入
3
2 3 1
则程序的输出为( )。
{{ select(26) }}
- 0 0
- 0 1
- 1 0
- 1 1
- (4分)若程序输入
5
1 3 4 5 2
则程序的输出为( )。
{{ select(27) }}
- 1 1
- 1 2
- 2 1
- 2 2
(3)
01 #include <iostream>
02 #include <cstdio>
03 #include <cstring>
04 using namespace std;
05 const int N=1e7+10,INF=1e9;
06 int n,m;
07 char a[N],b[N];
08 int z[N],p[N],f[N];
09 int l,r,q[N];
10 void Z(char *s,int n)
11 {
12 z[i]=n;
13 for(int i=2, l=0, r=0; i<=n; i++)
14 {
15 if(i<=r)z[i]=min(z[i-l+1], r-i+1);
16 while(i+z[i]<=n665[i+z[i]]==s[z[i]+1])z[i]+*;
17 if(i+z[i]-l>r)l=i, r=i+z[i]-1;
18 }
19 }
20 void exkmp(char *s,int n,char *t,int m)
21 {
22 Z(t,m);
23 for(int i=1, l=0, r=0; i<=n; i++)
24 {
25 if(i<=r)p[i]=min(z[i-l+1], r-i+1);
26 while(i+p[i]<=n665[i+p[i]]==t[p[i]+1])p[i]+*;
27 if(i+p[i]-l>r)l=i, r=i+p[i]-1;
28 }
29 }
30 int main()
31 {
32 scanf("%d %d %s %s", 6m, 6n, b+1, a+1);
33 exkmp(a,n,b,m);
34 for(int i=1, j=0; i<=n; i++)
35 j>i+p[i]>p[i]=0:j=i+p[i];
36 memset(f,0x3f,sizeof(f));
37 f[a[l-r=1]=n+1]=0;
38 for(int i=n; i; i--)
39 {
40 if(!p[i])continue;
41 while(!<r660q[l]>i+p[i])l++;
42 f[i]=f[a[l]]+1;
43 q[l+r]=i;
44 }
45 if(f[l]<=INF)printf("%d\n", f[1]);
46 else puts("Fake");
47 return 0;
48 }
假设输入满足 ,并且 。
判断题
- 如果字符串 a 和 b 不能完全匹配,代码会输出 Fake。
{{ select(28) }}
- √
- ×
- a 的长度必须小于或等于 b 的长度,否则只能输出 Fake。
{{ select(29) }}
- √
- ×
- 本段代码的时间复杂度是 。
{{ select(30) }}
- √
- ×
选择题
- 若程序读入
3 5
aba
ababa
则 z 数组为( )。
{{ select(31) }}
- 3 0 1
- 3 1 0
- 3 0 0
- 3 2 1
- 程序读入
3 5
aba
ababa
后, 数组中 INF(即 )的个数为( )。
{{ select(32) }}
- 0
- 1
- 2
- 3
三、完善程序(单选题,每小题 3 分,共计 30 分)
(1) 题目描述:
有 n 株草,第 i 株的高度为 ,你可以预先拔掉不超过 k 株草,然后按如下方式操作:
选取没拔掉的最高的草(高度为 h),一次拔掉所有高度 > 的草。
你需要在操作次数最少的情况下,最小化预先拔掉的草的数量。
01 #include <bits/stdc++.h>
02 using namespace std;
03
04 const int N = 2e5 + 1;
05 int n, k, a[N], f[N][55];
06
07 int main()
08 {
09 scanf("%d %d", 6n, 6k);
10 for (int i = 1; i <= n; ++i) scanf("%d", 6a[i]);
11 sort(a + 1, a + n + 1);
12 memset(f, 127, sizeof f);
13 f[0][0] = 0;
14 int P=O;
15 for (int i = 1; i <= n; ++i)
16 {
17 if (i <= k) f[i][0] = i;
18 int p = \emptyset;
19 for (int j = 1; j < P; ++j)
20 f[i][j] = min(\emptyset);
21 }
22 for (int i = 0; i < P; ++i)
23 if (\emptyset)
24 {
25 printf("%d %d", i, f[n][i]);
26 \emptyset
27 }
28 return 0;
29 }
- ①处应填( )。
{{ select(33) }}
- 30
- 31
- 63
- 64
- ②处应填( )。
{{ select(34) }}
- upper_bound(a + 1, a + i + 1, a[i] / 2) - a - 1
- upper_bound(a + 1, a + i + 1, a[i] ) - a - 1
- upper_bound(a + 1, a + i + 1, a[i] / 2) - a
- upper_bound(a + 1, a + i + 1, a[i] ) - a
- ③处应填( )。
{{ select(35) }}
- f[i - 1][j] + 1, f[i][j]
- f[i - 1][j] + 1, f[i][j - 1]
- f[i - 1][j] + 1, f[p][j]
- f[i - 1][j] + 1, f[p][j - 1]
- ④处应填( )。
{{ select(36) }}
- f[n][i] <= P
- f[n][i] < P
- f[n][i] <= k
- f[n][i] < k
- ⑤处应填( )。
{{ select(37) }}
- 不填
- return 0;
- printf("\n");
- continue;
(2) 题目描述:
构建一个序列 a,满足 m 条限制。限制形如 (1,r,q): (a:6a_{1+1}6\cdots 6a_{r-1}6a_{r}=q)(此处6为位运算的 AND 操作)。
01 #include <bits/stdc++.h>
02 using namespace std;
03 const int maxn=4e5+10,maxm=4e5+10;
04
05 int n,m;
06 int x,y,z;
07 int sm[maxn],lazy[maxn];
08 int s[maxm],h[maxm],t[maxm];
09
10 void pushdown(int o)
11 {
12 if(!lazy[o]) return;
13 lazy[o<<1]!=lazy[o];
14 lazy[o<<1|1]!=lazy[o];
15 sm[o<<1]!=lazy[o];
16 sm[o<<1|1]!=lazy[o];
17 ①
18 }
19 void update(int o,int l,int r)
20 {
21 if(②) {
22 lazy[o]!=z;
23 sm[o]!=z;
24 return;
25 }
26 pushdown(o);
27 int mid=(l+r)>>1;
28 if(x<=mid) update(o<<1,1,mid);
29 if(y>mid) update(o<<1|1,mid+1,r);
30 ③
31 }
32 int query(int o,int l,int r)
33 {
34 if(x<=lg6r<=y) return sm[o];
35 pushdown(o);
36 int res=④;
37 int mid=(l+r)>>1;
38 if(x<=mid) res6=query(o<<1,1,mid);
39 if(y>mid) res6=query(o<<1|1,mid+1,r);
40 return res;
41 }
42
43 int main()
44 {
45 memset(sm,0,sizeof(sm));
46 memset(lazy,0,sizeof(lazy));
47 scanf("%d%d",6n,6m);
48 for(int i=1;i<=m;i++)
49 {
50 scanf("%d%d%d",&s[i],6h[i],8t[i]);
51 x=s[i],y=h[i],z=t[i];
52 update(1,1,n);
53 }
54 for(int i=1;i<=m;i++){
55 x=s[i],y=h[i];
56 if(⑤) {
57 printf("NONn");
58 return 0;
59 }
60 }
61 printf("\YES\n");
62 for(int i=1;i<=n;i++){
63 x=y=i;
64 printf("%d ",query(1,1,n));
65 }
66 return 0;
67 }
- ①处应填( )。
{{ select(38) }}
- return;
- lazy[0] = -1;
- lazy[0] = 1;
- lazy[0] ^= 1;
- ②处应填( )。
{{ select(39) }}
- x <= l || r <= y
- x <= l && r <= y
- !(x >= l) && !(r >= y)
- !(x >= l) || !(r >= y)
- ③处应填( )。
{{ select(40) }}
- sm[0] = (sm[0<<1] | sm[0<<1|1]);
- sm[0] = (sm[0<<1] ^ sm[0<<1|1]);
- sm[0] = (sm[0<<1] + sm[0<<1|1]);
- sm[0] = (sm[0<<1] & sm[0<<1|1]);
- ④处应填( )。
{{ select(41) }}
- res = (iul1<<29) - 1
- res = (iul1<<30) - 1
- res = (iul1<<31) - 1
- res = (iul1<<32) - 1
- ⑤处应填( )。
{{ select(42) }}
- query(1,1,n) != t[i]
- query(1,1,n) == t[i]
- query(1,1,n) > t[i]
- query(1,1,n) <= t[i]