A. 梦熊联盟 · CSP-S 2024 提高级初赛考前模拟卷
梦熊联盟 · CSP-S 2024 提高级初赛考前模拟卷
该比赛已结束,您无法在比赛模式下递交该题目。您可以点击“在题库中打开”以普通模式查看和递交本题。
一、单项选择题(共 15 题,每题 2 分,共计 30 分;每题有且仅有一个正确选项)
- Linux 操作系统中,以下哪个命令是分页显示普通文本类型文件 
csp?{{ select(1) }} 
- A. 
vi csp - B. 
more csp - C. 
cat csp - D. 
ls csp 
- 表达式 
(1 + 34) * 5 - 56 / 7的后缀表达式为( )。{{ select(2) }} 
- A. 
1 34 + 5 * 56 7 / - - B. 
1 + 34 * 5 - 56 / 7 - C. 
- * + 1 34 5 / 56 7 - D. 
1 34 + 5 56 7 - * / 
- 调试工具 GDB 中的不进入函数的单步执行语句的调试命令是( )。{{ select(3) }}
 
- A. 
next或n - B. 
step或s - C. 
break或b - D. 
continue或c 
- 小明和小杨轮流掷硬币(每次掷硬币正面朝上概率是 ,反面朝上的概率是 ),小明先掷,如果谁先掷到正面算谁赢,请问小明赢的概率是( )。{{ select(4) }}
 
- A.
 - B.
 - C.
 - D.
 
- 以下哪个说法是正确的?( ){{ select(5) }}
 
- A. CSP-S 初赛交卷后考试没结束前可以回考场取遗忘的身份证
 - B. CSP-S 的认证选手可携带已关机的手机放在自己身边的包里
 - C. CSP-S 的认证选手在认证时间内上厕所的时候可携带手机
 - D. CCF 全称是中国计算机学会
 
- 解决区间查询 RMQ 问题通常使用( )。{{ select(6) }}
 
- A. 哈夫曼树
 - B. 并查集
 - C. 哈希表
 - D. 稀疏表
 
- 由 五个不同数值的点构成的二叉搜索树有( )种。{{ select(7) }}
 
- A.
 - B.
 - C.
 - D.
 
- 
假设我们有以下的 C++ 代码:
unsigned char a = 143, b = 3, c = 4; a <<= 2; int res = a | (b + c >> 1);请问,
res的值是多少?( ){{ select(8) }} 
- A. 63
 - B. 61
 - C. 573
 - D. 575
 
- 关于贪心算法,下面的说法哪些是不正确的?( ){{ select(9) }}
 
- A. 哈夫曼编码用到了贪心算法的思想
 - B. 最小生成树的 Prim 算法用到了贪心算法的思想
 - C. 0-1 背包问题可以用贪心算法解决
 - D. 最小生成树的 Kruskal 算法用到了贪心算法的思想
 
- 下列说法中哪个关于图的说法不正确?( ){{ select(10) }}
 
- A. 判定一个无向图是否为连通图可以从任意一点出发用 DFS 算法进行搜索
 - B. 对于有向图,如果拓扑排序可以完成,则说明图中有环
 - C. 标准的 Bellman–Ford 算法中会进行松弛操作
 - D. 除 Tarjan 算法外,还可以使用 Kosaraju 算法来求解强连通分量
 
- 设文本串为 ,其长度为 ,模式串为 ,其长度为 ,则 KMP 算法的时间复杂度为( )。{{ select(11) }}
 
- A.
 - B.
 - C.
 - D.
 
- 设 
A = true,B = false,C = false,D = true,以下逻辑运算表达式值为假的是( )。{{ select(12) }} 
- A.
 - B.
 - C.
 - D.
 
- BFS 算法通常会用到的数据结构是( )。{{ select(13) }}
 
- A. binary tree
 - B. list
 - C. stack
 - D. queue
 
- 若三个正整数 的位数之和为 ,且组成 的 个数码能排列为 ,则称 为“幸运数组”,例如 是一个幸运数组。满足 的幸运数组 的个数为( )。{{ select(14) }}
 
- A.
 - B.
 - C.
 - D.
 
- 
假设有以下的 C++ 代码:
int a[] = {1, 1, 3, 3, 5, 7, 9}; cout << (lower_bound(a, a + 7, 3) - a) << " "; cout << (upper_bound(a, a + 7, 7) - a) << endl;请问,上述输出的值是什么?( ){{ select(15) }}
 
- A. 
2 5 - B. 
1 5 - C. 
2 6 - D. 
1 6 
二、阅读程序(程序输入不超过数组或字符串定义的范围;判断题正确填 √,错误填 ×;除特殊说明外,判断题 1.5 分,选择题 3 分,共计 40 分)
- 
01 #include <bits/stdc++.h> 02 using namespace std; 03 int t, n, m, q, k, a, b; 04 vector<pair<int,int> >G; 05 bool vis[1001]; 06 bool dfs(int now, int dep) { 07 if(now == m) return true; 08 int u = G[now].first, v = G[now].second; 09 while((vis[u] || vis[v]) && now < m) { 10 now++; 11 if(now == m) break; 12 u = G[now].first, v = G[now].second; 13 } 14 if(now == m) return true; 15 if(dep == k) return false; 16 bool res = false; 17 vis[u] = 1; 18 res |= dfs(now + 1, dep + 1); 19 vis[u] = 0; 20 vis[v] = 1; 21 res |= dfs(now + 1, dep + 1); 22 vis[v] = 0; 23 return res; 24 } 25 int main() { 26 cin >> n >> m >> q; 27 k = n - q; 28 for(int i = 1; i <= m; i++) { 29 cin >> a >> b; 30 G.push_back({a, b}); 31 } 32 if(dfs(0, 0)) cout << "Yes\n"; 33 else cout << "No\n"; 34 } 
判断题
- 若交换 14、15 行,程序运行结果不会改变。{{ select(16) }}
 
- √
 - ×
 
- 若将 30 行改为 
G.push_back({b,a});,程序运行结果不会改变。{{ select(17) }} 
- √
 - ×
 
- 该程序的存图方式为邻接表法。{{ select(18) }}
 
- √
 - ×
 
- 若删除 19 行,则程序运行结果可能会发生改变;但删去 22 行则不会。{{ select(19) }}
 
- √
 - ×
 
选择题
- 本程序的时间复杂度是( )。{{ select(20) }}
 
- A.
 - B.
 - C.
 - D.
 
- 已知输入的 ,,对应的  组  分别为 。请问  至多为多少时可以输出 
Yes?( ){{ select(21) }} 
- A.
 - B.
 - C.
 - D.
 
- 
01 #include <bits/stdc++.h> 02 using namespace std; 03 const int mod = 1e9 + 7; 04 long long dp[(1<<17)+2], a[20], n, k; 05 int main(){ 06 cin >> n >> k; 07 for(int i = 0; i < n; i++){ 08 cin >> a[i]; 09 if(a[i] > k) return cout << 0, 0; 10 } 11 dp[0] = 1; 12 for(int i = 0; i < (1 << n); i++){ 13 for(int j = 0; j < n; j++){ 14 if(i >> j & 1) continue; 15 dp[i | 1<<j] = (dp[i | 1<<j] + dp[i]) % mod; 16 for(int u = 0; u < n; u++){ 17 if(i >> u & 1) continue; 18 if(j == u) continue; 19 if(a[j] + a[u] > k) continue; 20 int now = i | (1 << j) | (1 << u); 21 dp[now] = (dp[now] + dp[i]) % mod; 22 } 23 } 24 } 25 cout << dp[(1<<n)-1] << endl; 26 } 
判断题
- 若将第 11 行的语句删除,则无论输入是什么,程序的输出都是 
0。{{ select(22) }} 
- √
 - ×
 
- 第 20 行定义的 
now在任何时候都大于等于 3。{{ select(23) }} 
- √
 - ×
 
- 若输入的 
n为 17,则程序会发生数组越界的情况。{{ select(24) }} 
- √
 - ×
 
- 若删除第 9 行,则程序的结果可能会发生改变。{{ select(25) }}
 
- √
 - ×
 
选择题
- (2 分)若输入为 
2 5 3 4(前两个数为 ,后两个数为 ),则输出为( )。{{ select(26) }} 
- A. 
1 - B. 
2 - C. 
3 - D. 
4 
- 若输入为 
4 6 2 3 4 5(前两个数为 ,后四个数为 ),则输出为( )。{{ select(27) }} 
- A. 
120 - B. 
60 - C. 
48 - D. 
24 
- 
01 #include<bits/stdc++.h> 02 const int maxn = 1000; 03 using namespace std; 04 struct node{ 05 int weight; 06 int parent, lchild, rchild; 07 }; 08 int s1, s2, w[maxn], n, res[maxn]; 09 char ans[maxn]; 10 node HT[maxn]; 11 void getMin(int x){ 12 int min1 = 0x3f3f3f3f, min2 = 0x3f3f3f3f; 13 for(int i = 1; i <= x; i++){ 14 if(HT[i].parent) continue; 15 int val = HT[i].weight; 16 if(val < min1){ 17 min2 = min1; 18 s2 = s1; 19 min1 = val; 20 s1 = i; 21 }else if(val < min2){ 22 min2 = val; 23 s2 = i; 24 } 25 } 26 } 27 void init(){ 28 int m = 2 * n - 1; 29 for(int i = 1; i <= m; i++) { 30 if(i <= n) 31 HT[i].weight = w[i]; 32 else 33 HT[i].weight = 0; 34 HT[i].parent = HT[i].lchild = HT[i].rchild = 0; 35 } 36 for(int i = n + 1; i <= m; i++){ 37 getMin(i-1); 38 HT[s1].parent = HT[s2].parent = i; 39 HT[i].lchild = s1; 40 HT[i].rchild = s2; 41 HT[i].weight = HT[s1].weight + HT[s2].weight; 42 } 43 for(int i = 1; i <= n; i++){ 44 char s[maxn]; 45 int cnt = 0; 46 int start = n - 1, c, f; 47 for(c=i,f=HT[i].parent; f!=0; c=f,f=HT[f].parent){ 48 if(HT[f].lchild == c) 49 s[cnt] = '0'; 50 else 51 s[cnt] = '1'; 52 cnt++; 53 } 54 cout << ans[i] << " "; 55 for(int j = cnt - 1; j >= 0; j--) 56 cout << s[j]; 57 cout << endl; 58 } 59 } 60 int main(){ 61 string s; 62 cin >> s; 63 int cnt[200] = {}; 64 for(int i = 0; i < s.size(); i++){ 65 cnt[s[i]]++; 66 } 67 for(int i = 1; i < 200; i++){ 68 if(cnt[i] != 0){ 69 w[++n] = cnt[i]; 70 ans[n] = i; 71 res[n] = cnt[i]; 72 } 73 } 74 init(); 75 }保证输入的字符串只包含大写英文字母。
 
判断题
- 为了避免程序崩溃,输入字符串 
s的长度至多为 999,即被maxn限制。{{ select(28) }} 
- √
 - ×
 
- (2 分)若输入的字符串 
s的所有字符全相同,则程序不会输出任何数字。{{ select(29) }} 
- √
 - ×
 
getMin函数的功能可以用优先队列或set替代,从而优化程序的时间复杂度。{{ select(30) }}
- √
 - ×
 
选择题
- 该程序的时间复杂度为( )。{{ select(31) }}
 
- A.
 - B.
 - C.
 - D.
 
- 若输入字符串 
s为CSPCSP,则程序输出的数位的个数之和为( )。{{ select(32) }} 
- A. 4
 - B. 3
 - C. 6
 - D. 5
 
- 若输入字符串 
s为AKAKCSP,则程序输出时哪两个字母后面的有三个数位( )。{{ select(33) }} 
- A. 
C P - B. 
S P - C. 
C S - D. 
A K 
- 若输入字符串 
s为AKAKCSP,则程序输出时A后面的数字为( )。{{ select(34) }} 
- A. 
10 - B. 
01 - C. 
101 - D. 
111 
三、完善程序(单选题,每小题 3 分,共计 30 分)
- 
(树的染色)给一棵至多包含 个点的无根树,初始每个点都是白色的,你每次可以选择一个白点变成黑色。第一次可以任选,之后每次选择的白点都必须和至少一个黑点相邻。选择一个白点变黑可以得到的收益是这个白点所在的连通块大小,当树的所有点全部变黑时结束。请问你最多可以获得多少收益?

例如本图中最大收益为 ,每次选点分别为 ,每一步所得收益为 求和得到 。注意:第一次选 号点,第二次选 号点是非法的,因为第二次选点没有和一个黑点相邻。当然, 也是一种合法且收益最大的选择。
提示:我们令第一个选择的点为树根,不难发现,当根节点确定时,整棵树的选择及收益都确定了。所以此题难点在于如何寻找第一个点。考虑换根 DP,设 为以 为根的收益,我们通过一个 的值来推得以其他点为根的收益。试完成代码。
01 #include <bits/stdc++.h> 02 using namespace std; 03 #define ll long long 04 const int maxn = 2e5 + 5; 05 vector <int> G[maxn]; 06 ll sz[maxn], dp1[maxn], dp2[maxn], n, ans = 0; 07 long long dfs(int now, int pre){ 08 sz[now] = 1; 09 for(int i = 0; i < G[now].size(); i++){ 10 int nxt = G[now][i]; 11 if(nxt == pre) continue; 12 sz[now] += dfs(nxt, now); 13 ➀; 14 } 15 dp1[now] += sz[now]; 16 return sz[now]; 17 } 18 void dfs2(int now, int pre){ 19 dp2[now] = ➁; 20 for(int i = 0; i < G[now].size(); i++){ 21 int nxt = G[now][i]; 22 if(nxt == pre) continue; 23 dp2[nxt] = ➂; 24 dfs2(nxt, now); 25 } 26 ans = max(ans, dp2[now]); 27 } 28 int main(){ 29 cin >> n; 30 for(int i = 1; i < n; i++){ 31 int a, b; 32 cin >> a >> b; 33 G[a].push_back(b); 34 G[b].push_back(a); 35 } 36 ➃ 37 cout << ans << endl; 38 } 
- ➀处应填( )。{{ select(35) }}
 
- A. 
dp1[now] = max(dp1[now], dp1[nxt]) - B. 
dp1[now] += dp1[nxt] - C. 
dp1[now] += sz[nxt] - D. 
dp1[now] = max(dp1[now], sz[nxt]) 
- ➁处应填( )。{{ select(36) }}
 
- A. 
1 - B. 
dp1[now] - C. 
sz[now] - D. 
now == 1 ? dp1[now] : dp2[now] 
- ➂处应填( )。{{ select(37) }}
 
- A. 
dp2[now] + n - sz[nxt] - sz[nxt] - B. 
dp2[now] + n - sz[nxt] - sz[now] - C. 
dp2[now] + n - sz[now] - sz[now] - D. 
dp2[now] + sz[nxt] + sz[now] 
- ➃处应填( )。{{ select(38) }}
 
- A. 
dfs2(1,1); dfs(1,1); - B. 
dfs2(1,n); dfs(1,1); - C. 
dfs(1,1); dfs2(1,n); - D. 
dfs(1,1); dfs2(1,1); 
- 
(入度)给定一张 个点、 条边的简单无向图,每条边有一个权值,你可以任选一些边并给这些边定向,使得每个点的入度均为 。问是否能够做到,若能,则输出所选边的最大权值和;否则输出
impossible。思路:将所有边排序,然后逐个添加,用并查集维护添加边之后是否有某个点不得不出现两条入边的情况。
01 #include <bits/stdc++.h> 02 using namespace std; 03 struct node{ 04 int u, v, val; 05 }; 06 bool cmp(node a, node b){ 07 return ➀; 08 } 09 const int maxn = 100005; 10 node a[maxn]; 11 int f[maxn], flag[maxn]; 12 int Find(int x){ 13 return f[x] == x ? x : f[x] = Find(f[x]); 14 } 15 void Union(int x, int y){ 16 int fx = Find(x), fy = Find(y); 17 f[fx] = fy; 18 ➁; 19 } 20 int main(){ 21 int n, m, t; 22 cin >> t; 23 while(t--){ 24 long long cnt=0, ans=0; 25 cin >> n >> m; 26 for(int i = 1; i <= n; i++){ 27 f[i] = i; 28 flag[i] = 1; 29 } 30 for(int i = 1; i <= m; i++) 31 cin >> a[i].u >> a[i].v >> a[i].val; 32 sort(a+1, a+1+m, cmp); 33 for(int i = 1; i <= m; i++){ 34 int x = a[i].u, y = a[i].v; 35 int fx = Find(x), fy = Find(y); 36 if(fx == fy && ➂){ 37 ➃; 38 cnt++; 39 ans += a[i].val; 40 }else if(fx != fy && ➄){ 41 Union(fx, fy); 42 cnt++; 43 ans += a[i].val; 44 } 45 } 46 if(➅){ 47 cout << ans << endl; 48 }else{ 49 cout << "impossible" << endl; 50 } 51 } 52 } 
- ➀处应填( )。{{ select(39) }}
 
- A. 
a.u < b.u - B. 
a.u > b.u - C. 
a.val > b.val - D. 
a.val < b.val 
- ➁处应填( )。{{ select(40) }}
 
- A. 
flag[fx] = flag[fy] - B. 
flag[fx] &= flag[fy] - C. 
flag[fx] |= flag[fy] - D. 
flag[fx] ^= flag[fy] 
- ➂处应填( )。{{ select(41) }}
 
- A. 
flag[fx]==1 - B. 
flag[fx]==0 - C. 
cnt==n - D. 
cnt!=n 
- ➃处应填( )。{{ select(42) }}
 
- A. 
flag[fx] = 1 - B. 
flag[fx] = 0 - C. 
f[fx] = fy - D. 
Union(fx, fy) 
- ➄处应填( )。{{ select(43) }}
 
- A. 
(flag[fx] || flag[fy]) - B. 
flag[fx] && flag[fy] - C. 
flag[fx]==0&&flag[fy]==0 - D. 
(flag[fx] ^ flag[fy]) 
- ➅处应填( )。{{ select(44) }}
 
- A. 
cnt == n - B. 
cnt == n / 2 - C. 
flag[n] == 1 - D. 
flag[n] == 0 
【MX-s1】梦熊 CSP-S 2024 初赛模拟
- 状态
 - 已结束
 - 规则
 - IOI
 - 题目
 - 1
 - 开始于
 - 2024-9-17 14:30
 - 结束于
 - 2024-9-17 16:30
 - 持续时间
 - 2 小时
 - 主持人
 - 参赛人数
 - 700