#157. 2024 CSP-S 满分之路 模拟卷三

2024 CSP-S 满分之路 模拟卷三

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

  1. 下面的代码属于哪个算法的核心代码?( )
Long Long c[20][20];
c[0][0] = 1;
for (int i = 1; i <= n; i++) {
    c[i][0] = c[i][i] = 1;
    for (int j = 1; j < i; j++) {
        c[i][j] = c[i - 1][j - 1] + c[i - 1][j];
    }
}

{{ select(1) }}

  • 0-1背包
  • 杨辉三角形
  • 完全背包
  • 部分背包
  1. NOI Linux2.0中缺省指定编译的C++版本是( )。 {{ select(2) }}
  • C++03
  • C++17
  • C++11
  • C++14
  1. 下列属于视频文件格式的是( )。 {{ select(3) }}
  • PNG
  • AVI
  • JPEG
  • BMP
  1. 以下不属于常见的平衡树的是( )。 {{ select(4) }}
  • AVL
  • 伸展树
  • 三叉树
  • 红黑树
  1. 字符串"dededfede"和字符串"defed"的最长公共子串是( )。 {{ select(5) }}
  • fed
  • defed
  • def
  • de
  1. 下面哪个操作不属于二叉搜索树的常见操作?( ) {{ select(6) }}
  • 查找
  • 插入
  • 删除
  • 交换排序
  1. 具有m个顶点、n条边的有向图采用邻接表存储结构,进行深度优先遍历运算的时间复杂度是( )。 {{ select(7) }}
  • (O(m))
  • (O(n))
  • (O(m + n))
  • (O(nm))
  1. 将关键码集合(100, 300, 800, 70, 500, 900)逐一保存在一张长度为100的哈希表中。选取哈希函数为Hash(key) = key / 100,则500保存在表中的位置应该是( )。 {{ select(8) }}
  • 5
  • 6
  • 7
  • 8
  1. 设树T的高度为4,其中度为1、2、3和4的结点个数分别为4、2、1、1,则T中的叶子结点数为( )。 {{ select(9) }}
  • 5
  • 6
  • 7
  • 8
  1. 在C++程序中执行cout << (928 > 7 > 6)会输出什么结果?( ) {{ select(10) }}
  • 1
  • 0
  • true
  • false
  1. 已知240个一模一样的小球里面有一个次品,比正常球轻一些。现在有一架天平(每一端都可以放下240个小球),请问最少称重几次可以找出这个次品小球?( ) {{ select(11) }}
  • 6
  • 4
  • 5
  • 7
  1. 正六边形的中心和顶点共7个点,以其中3个点为顶点的三角形共有( )个。 {{ select(12) }}
  • 30
  • 35
  • 32
  • 28
  1. 下面的C++代码运行后,输出的是( )。
#include<bits/stdc++.h>
using namespace std;
int main()
{
    int a[100] = {1, 2}; 
    string s = "CSP-S";
    cout << s[a[2]] << endl; 
    return 0;
}

{{ select(13) }}

  • C
  • S
  • P
  • CSP-S
  1. 由数字0,1,2,3,4,5组成没有重复数字的六位数,其中个位数字小于十位数字的共有( )个。 {{ select(14) }}
  • 210
  • 300
  • 464
  • 600
  1. 已知元素(7, 25, 14, 87, 51, 90, 5, 19, 20),问这些元素以怎样的顺序进入栈,才能使出栈的顺序满足:7在51的前面;90在87的后面;20在14的后面;25在5的前面;19在90的后面?( ) {{ select(15) }}
  • 20, 5, 7, 51, 90, 25, 14, 19, 87
  • 51, 5, 19, 20, 14, 8, 87, 90, 25
  • 19, 20, 90, 7, 5, 25, 51, 14, 87
  • 5, 25, 51, 7, 20, 19, 90, 87, 14

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

(1)

01 #include <iostream>
02 using namespace std;
03 
04 const int mod = 1e9 + 7;
05 const int N = 1010, C = 10010;
06 int nn, CC;
07 Long long a[2][C], b[2][C];
08 
09 int main() {
10     cin >> nn >> CC;
11     a[1][0] = 1; b[1][0] = 1;
12     for (int n = 2; n <= nn; n++) {
13         for (int c = min(CC, (n - 1) * (n - 2) / 2) + 1; c <= min(CC, n * (n - 1) / 2); c++) {
14             b[(n - 1) & 1][c] = b[(n - 1) & 1][c - 1];
15         }
16         a[n & 1][0] = 1; b[n & 1][0] = 1;
17         for (int c = 1; c <= min(CC, n * (n - 1) / 2); c++) {
18             int en = max(c - n + 1, 0);
19             a[n & 1][c] = b[(n - 1) & 1][c];
20             if (en > 0) a[n & 1][c] -= b[(n - 1) & 1][en - 1];
21             a[n & 1][c] %= mod;
22             if (a[n & 1][c] < 0) a[n & 1][c] += mod;
23             b[n & 1][c] = b[n & 1][c - 1] + a[n & 1][c];
24             b[n & 1][c] %= mod;
25         }
26     }
27     cout << a[nn & 1][CC] << endl;
28     return 0;
29 }

■ 判断题 16. 输入为"10 1"时,输出为"10"。( ) {{ select(16) }}

  • 正确
  • 错误
  1. 输入为"4 3"时,输出为"6"。( ) {{ select(17) }}
  • 正确
  • 错误
  1. 本题与计算逆序对有关。( ) {{ select(18) }}
  • 正确
  • 错误
  1. 第16行可以放到第13行前面,程序的运行结果不会改变。( ) {{ select(19) }}
  • 正确
  • 错误

■ 选择题 20. 本程序的时间复杂度是( )。 {{ select(20) }}

  • (O\left(n^{2}\right))
  • (O\left(n^{3}\right))
  • (O\left(n^{2} log n\right))
  • (O\left(n^{4}\right))
  1. 数组a、b的调用经常有"&1"的操作,这是为了( )。 {{ select(21) }}
  • 没什么意义,干扰读题
  • 用位运算快速减一
  • 快速取二进制尾数
  • &运算符用于获取存储地址

(2)

01 #include <iostream>
02 #include <iomanip>
03 #include <math.h>
04 using namespace std;
05 pair<long long, long long> calc(int n, long long m) {
06     if (n == 0) return make_pair(0, 0);
07     long long len = 1LL << (n - 1), cnt = 1LL << (2 * n - 2);
08     pair<long long, long long> pos = calc(n - 1, m % cnt);
09     long long z = m / cnt; 
10     long long x = pos.first, y = pos.second;
11     if (z == 0) return make_pair(y, x);
12     if (z == 1) return make_pair(x, y + len);
13     if (z == 2) return make_pair(x + len, y + len);
14     if (z == 3) return make_pair(2 * len - y - 1, len - x - 1);
15 }
16 int main() {
17     int n, p, q;
18     cin >> n >> p >> q;
19     cout << setprecision(3)
20          << sqrt(pow(1.0 * calc(n, p).first - calc(n, q).first, 2.0)
21          + pow(1.0 * calc(n, p).second - calc(n, q).second, 2.0))
22          << endl;
23     return 0;
24 }

■ 判断题 22. 本程序编译会报warning。( ) {{ select(22) }}

  • 正确
  • 错误
  1. 若想程序不出错,p、q不能超过(2^{2n})。( ) {{ select(23) }}
  • 正确
  • 错误
  1. 输入数据符合要求时,本程序的时间复杂度是(O(max{N, log M}))。( ) {{ select(24) }}
  • 正确
  • 错误

■ 选择题 25. 若输入为"2 0 10",输出为( )。 {{ select(25) }}

  • 4.243
  • 3.00
  • 4.24
  • 3.606
  1. 当(|p - q| = 1)时,不论输入的n是多少,只要p、q在符合要求的范围内,则输出为( )。 {{ select(26) }}
  • 1
  • 2
  • -1
  • 0
  1. 对同一个n,共有几种输入,可以让输出达到最大?( ) {{ select(27) }}
  • 2
  • 4
  • 1
  • 8

(3)

01 #include <iostream>
02 using namespace std;
03 
04 const int N = 500010;
05 int n;
06 long long ans, mod = 100000007;
07 long long a[N], b[N], A[N], B[N], sa[N], sb[N];
08 
09 int main() {
10     cin >> n;
11     for (int i = 1; i <= n; i++) {
12         cin >> a[i]; 
13         A[i] = A[i - 1] + a[i];
14         A[i] %= mod;
15         sa[i] = sa[i - 1] + A[i];
16         sa[i] %= mod;
17     }
18     for (int i = 1; i <= n; i++) {
19         cin >> b[i];
20         B[i] = B[i - 1] + b[i];
21         B[i] %= mod;
22         sb[i] = sb[i - 1] + B[i];
23         sb[i] %= mod;
24     }
25     long long t;
26     for (int i = 0; i <= n; i++) {
27         t = A[i];
28         t *= B[i]; t %= mod;
29         t *= n; t %= mod;
30         ans += t;
31         ans %= mod;
32     }
33     for (int i = 0; i < n; i++) {
34         t = A[i] * (sb[n] - sb[i]);
35         t %= mod;
36         ans -= t;
37         if (ans < 0) ans += mod;
38         t = B[i] * (sa[n] - sa[i]);
39         t %= mod;
40         ans -= t;
41         ans %= mod;
42         if (ans < 0) ans += mod;
43     }
44     cout << ans << endl;
45     return 0;
46 }

■ 判断题 28. 因为有第39行,所以若去掉第35行,程序结果不受影响。( ) {{ select(28) }}

  • 正确
  • 错误
  1. 去掉第37行,程序结果不受影响。( ) {{ select(29) }}
  • 正确
  • 错误
  1. 第34行有溢出风险,必须按照第27-28行的方式来写。( ) {{ select(30) }}
  • 正确
  • 错误

■ 选择题 31. 若输入3 2 3 4 3 4 5,则输出为( )。 {{ select(31) }}

  • 243
  • 244
  • 253
  • 254
  1. 本题实际在计算( )。 {{ select(32) }}
  • (\sum_{r=1}^{n} \sum_{l=r}^{n}\left(\sum_{i=1}^{r} a_{i} * \sum_{i=1}^{r} b_{i}\right))
  • (\sum_{l=1}^{n} \sum_{r=1}^{n}\left(\sum_{i=1}^{r} a_{i} * b_{i}\right))
  • (\sum_{l=1}^{n} \sum_{r=1}^{n}\left(\sum_{i=1}^{r} a_{i} * \sum_{i=1}^{r} b_{l}\right))
  • (\sum_{l=1}^{n} \sum_{r=1}^{n}\left(\sum_{i=1}^{r} a_{i} * \sum_{i=1}^{r} b_{i}\right))
  1. (4分)本代码将原问题的时间复杂度从(O(N^{3}))优化到(O(N))。如果希望继续优化,应该( )。 {{ select(33) }}
  • 没有太大优化空间
  • 减少取模运算
  • long long改为int,以提高处理速度
  • 做更多的预处理

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

(1) **有一个字符串S,最开始其中只有一个字符a,之后你要对这个字符串进行若干次操作,每次将其中每一个字符c替换成某个字符串s(例如对于字符串ball,将其中的l替换为na后将得到banana)。现在给定(l, r),你需要输出变换完毕后,S的第l个字符到第r个字符对应的子串是什么。

算法是逆序建树,从最后一次操作开始,将字符替换的规则视为树的连线,叶子结点为最后被替换的字母。建树完毕后,再根据(l, r)的数值,在树上DFS遍历并输出。

01 #include <bits/stdc++.h>
02 using namespace std;
03 #define ll long long
04 const int NN = 2e5 + 10;
05 char c[NN]; string s[NN];
06 int first[26]; ll tot[NN], tf[26];
07 vector<ll> cnt[NN]; vector<int> nxt[NN];
08 
09 int num(char c) {
10     return ①;
11 }
12 
13 ll search(int cur, ll l, ll r, ll acc) {
14     for (int i = 0; i < cnt[cur].size(); i++) {
15         if (acc >= r) break;
16         if (acc + cnt[cur][i] >= l) {
17             if (!nxt[cur][i]) {
18                 cout << s[cur][i];
19                 acc++;
20             } else {
21                 ②;
22             }
23         } else {
24             acc += cnt[cur][i];
25         }
26     }
27     return acc;
28 }
29 
30 int main() {
31     ios_base::sync_with_stdio(false);
32     cin.tie(NULL);
33     ll l, r; int n;
34     cin >> l >> r >> n;
35     for (int i = 1; i <= n; i++) {
36         cin >> c[i] >> s[i];
37     }
38     for (int i = n; i > 0; i--) {
39         for (int j = 0; j < s[i].size(); j++) {
40             ③;
41         }
42         first[num(c[i])] = i;
43     }
44     for (int i = 0; i < 26; i++) tf[i] = 1;
45     for (int i = n; i > 0; i--) {
46         tot[i] = 0;
47         for (int j = 0; j < s[i].size(); j++) {
48             ④;
49             cnt[i].push_back(tf[k]);
50             tot[i] += tf[k];
51             if (tot[i] > r) break;
52         }
53         tf[num(c[i])] = tot[i];
54     }
55     ⑤;
56 }
  1. ①处应填( )。 {{ select(34) }}
  • c - a
  • c - 'a'
  • c - 'a' + 1
  • 'c' - 'a'
  1. ②处应填( )。 {{ select(35) }}
  • acc = search(acc, nxt[cur][i], l, r, acc)
  • acc = search(nxt[cur][i], -cnt[cur][i], r, acc)
  • acc = search(nxt[cur][i], l, r, acc)
  • acc = search(nxt[cur][i], l, r, acc + cnt[cur][i])
  1. ③处应填( )。 {{ select(36) }}
  • nxt[i].push_back(first[num(s[i][j])])
  • nxt[i].push_back(num(s[i][j]))
  • cnt[i].push_back(num(s[i][j]))
  • cnt[i].push_back(first[num(s[i][j])])
  1. ④处应填( )。 {{ select(37) }}
  • int k = 0
  • int k = num(c[i])
  • int k = num(s[i][j])
  • int k = first[num(s[i][j])]
  1. ⑤处应填( )。 {{ select(38) }}
  • search(first[1], l, r, nxt[0])
  • search(first[1], l, r, 0)
  • search(1, l, r, 1)
  • search(1, l, r, 0)

(2) 给定函数(h(x)),(x \in Z),(1 ≤ x ≤ n),定义seepairs(h)为这样的无序数对((i, j))的个数:(i < j),且连接((i, h(i)))与((j, h(j)))的线段不低于((k, h(k))),其中(i < k < j)。对h函数进行Q次调整,每次把(h(x))调整为(h(x) + y),(y > 0)。求每次调整之后的seepairs(h)

数据规模:n,(Q ≤ 2000),初始(h(x))和调整后的(h(x))都不超过(10^9)。

本代码使用set存储,初始化每个(h(i))能“看到”的点的数量see(i),则对see(i)求和即为seepairs(),每次调整(h(x))之后,因为(h(x))只增不减,所以see(x)只增不减。对于(i > x),see(i)不变,对于(i < x),see(i)只减不增,因此把see(1)see(x)调整之后再求和,即为调整后的seepairs(h)

01 #include <bits/stdc++.h>
02 using namespace std;
03 
04 const int N = 2010;
05 int n, q, x, y; long long h[N];
06 set<int> see[N];
07 typedef set<int>::iterator iter;
08 
09 bool small(int i, int k, int j) {
10     return ①;
11 }
12 
13 int main() {
14     cin >> n;
15     for (int i = 1; i <= n; i++) {
16         cin >> h[i];
17     }
18     for (int i = 1; i < n; i++) {
19         see[i].insert(i + 1);
20         for (int j = i + 2; j <= n; j++) {
21             ②;
22             see[i].insert(j);
23         }
24     }
25     cin >> q;
26     for (int qq = 1; qq <= q; qq++) {
27         cin >> x >> y;
28         h[x] += y;
29         for (int i = 1; i < x; i++) {
30             iter it = ③;
31             if (it == see[i].end()) {
32                 --it;
33                 if (small(i, *it, x)) see[i].insert(x);
34             } else {
35                 bool ins = false;
36                 if (*it == x) {
37                     ins = true;
38                     it++;
39                 } else {
40                     --it;
41                     if (small(i, *it, x)) {
42                         see[i].insert(x);
43                         ins = true;
44                         it++;
45                     }
46                 }
47                 ④;
48                 if (ins) {
49                     while (⑤) {
50                         it = see[i].erase(it);
51                     }
52                 }
53             }
54         }
55         if (x < n) {
56             see[x].clear();
57             see[x].insert(x + 1);
58             for (int j = x + 2; j <= n; j++) {
59                 if (small(x, *see[x].rbegin(), j)) see[x].insert(j);
60             }
61         }
62         int ans = 0;
63         for (int i = 1; i < n; i++) {
64             ans += see[i].size();
65         }
66         cout << ans << endl;
67     }
68     return 0;
69 }
  1. ①处应填( )。 {{ select(39) }}
  • (h[k] - h[i]) * (j - k) < (h[j] - h[k]) * (k - i)
  • (h[k] - h[i]) * (j - k) < (h[j] - h[k]) * (i - k)
  • (h[k] - h[i]) * (j - i) < (h[j] - h[i]) * (k - i)
  • (h[k] - h[i]) * (j - i) <= (h[j] - h[i]) * (k - i)
  1. ②处应填( )。 {{ select(40) }}
  • if (small(i, *see[i].rbegin(), j))
  • if (small(i, *see[i].rbegin(), j - 1))
  • if (small(i, *see[i].end(), j))
  • if (small(i, *see[i].end() - 1, j))
  1. ③处应填( )。 {{ select(41) }}
  • see[i].upper_bound(x)
  • see[i].lower_bound(x)
  • see[i].lower_bound(x) + 1
  • see[i].upper_bound(x + 1)
  1. ④处应填( )。 {{ select(42) }}
  • it--
  • it++
  • // 无内容
  • }
  1. ⑤处应填( )。 {{ select(43) }}
  • it != see[i].end() && small(i, x, *it)
  • it != see[i].end() - 1 && !small(i, x, *it)
  • it != see[i].end() && !small(i, x, *it)
  • it != see[i].end() && !small(i, x, it)