#2904. CSP-J 2023第一轮(初赛)模拟

CSP-J 2023第一轮(初赛)模拟

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

  1. 网址 www.sina.com.cn 当中,顶级域名是( ) 。

{{ select(1) }}

  • www
  • cn
  • com.cn
  • sina
  1. 以下物品可以携带进 CSP 第二轮测试考场的是( ) 。

{{ select(2) }}

  • 可以发出巨大响声的发光机械键盘
  • 写有 梁孟松 签名的《降龙十大掌》的封皮
  • 印有 stong9070 照片(已设法获得其授权)的文化衫 T 恤
  • 具有拍照功能的游标卡尺
  1. 将元素 a,b,c,d,e,f 依次入栈,则以下选项中出栈序列不可能是( ) 。

{{ select(3) }}

  • b,d,c,f,e,a
  • f,e,d,c,b,a
  • d,c,e,b,f,a
  • d,c,f,b,e,a
  1. 「流程结构」是编程中用于控制程序执行流程的一种方式.它包括顺序结构、分支结构和循环结构.在一些诗歌作品中,也有对「流程结构」的体现.下列诗歌片段中体现循环结构的是( ) 。

{{ select(4) }}

  • 如果还能找到你,就让风儿告诉你。——《Artificial Emotions》
  • 只要我还能够行走,只要我还能够张望,只要我还能够呼吸,就一直走向前方。——《Песня тревожной молодости》
  • 昔闻洞庭水,今上岳阳楼。——《登岳阳楼》
  • 啊如果我在,战斗中牺牲,啊朋友再见吧,再见吧,再见吧!如果我在,战斗中牺牲,你一定把我来埋葬。——《Bella Ciao》
  1. 已知两个二进制整数 𝑎, 𝑏;𝑎=1010001010(2) 𝑎 = 1010001010_{(2)};𝑏=1110100110(2) 𝑏 = 1110100110_{(2)}则表达式 (a&b)^(a|b) 的值为( )。

{{ select(5) }}

  • 0011011010(2)0011011010_{(2)}
  • 0100101100(2)0100101100_{(2)}
  • 0011010010(2)0011010010_{(2)}
  • 0100101000(2)0100101000_{(2)}
  1. 一个有 10 个节点的有向图,要使得每一个满足 1 ≤ 𝑖, 𝑗 ≤ 10,  𝑖 ≠ 𝑗 的点对 (𝑖,𝑗) 都存在一条从 𝑖 到达 𝑗 的路径,至少需要连( )条有向边。 {{ select(6) }}
  • 9
  • 10
  • 19
  • 20
  1. 观察下列代码
int a[] = {5, 4, 3, 2, 1};
auto p = a + 3;
auto q = &p;
(*q) ++;
auto k = *p;

其中, 𝑘 的类型以及 𝑘 的值分别为()。 {{ select(7) }}

  • int 类型,值为 1
  • int 类型,值为 3
  • int 指针类型,值为 𝑎 数组的下标为 3 的元素的地址
  • int 指针类型,值为 𝑎 数组的下标为 4 的元素的地址
  1. 中缀表达式 a+(b+c)-d*e/f 改写成后缀表达式为( )。 {{ select(8) }}
  • a b + c + d e * f / -
  • a b c + + d e * f / -
  • a b + c + d * e f / -
  • a b c + + d * e / f -
  1. 一张大小为 6114 × 8192 的 24 位彩色图片,使用 .bmp 格式存储,占用的空间大小约为( )。 {{ select(9) }}
  • 144 MiB
  • 288 MiB
  • 1152 MiB
  • 48 MiB

10.以下程序片段的时间复杂度为( ) 。

int cnt = 0;
  for(int i = 1;i <= n;i ++){
    for(int j = 1;j <= n;j += i){
       for(int k = 1;k <= n;k += j){
          ++ cnt;
      }
   }
}

提示:

$\frac{n}{1^1}+\frac{n}{2^1}+\frac{n}{3^1}+\cdots \frac{n}{n^1}\approx C_1\times \log n$

$\frac{n}{1^2}+\frac{n}{2^2}+\frac{n}{3^2}+\cdots \frac{n}{n^2}\approx C_2$

其中, 𝐶1,𝐶2𝐶_1, 𝐶_2 均为常数。 {{ select(10) }}

  • Θ(𝑛2)Θ(𝑛^2)
  • Θ(𝑛2log𝑛)Θ(𝑛^2 log 𝑛)
  • Θ(𝑛log𝑛)Θ(𝑛 log 𝑛)
  • Θ(𝑛log2𝑛)Θ(𝑛 log^2 𝑛)

11.依次抛出四个六面骰子,按照抛出顺序将骰子上的数值记为 𝑎, 𝑏, 𝑐, 𝑑。则 a < b;b > c; c< d 同时成立的概率为( )。 {{ select(11) }}

  • 95/648
  • 4/27
  • 5/27
  • 1/6

12.十进制小数 0.3,转写成八进制为( )。 {{ select(12) }}

  • 0.3
  • 0.2314631⋯
  • 0.2046204⋯
  • 0.3333333⋯

13.观察如下代码片段:

union U{
  bool flag1, flag2, flag3, flag4, flag5;
  signed short a;
  unsigned short b;
  enum E{
    CardA = 0, CardB = 1,
    CardC = 2, CardD = 142857
  } e;
} u;

其中, sizeof(u) 的值为( )。 {{ select(13) }}

  • 4
  • 8
  • 13
  • 16

14.已知某种可用来维护序列的数据结构,支持 Θ(log𝑛)Θ(log 𝑛) 向某个位置后面插入元素、Θ(𝑛)Θ(𝑛) 查询某个元素的排名, Θ(𝑛log𝑛)Θ(𝑛 log 𝑛) 遍历整个序列,那么用上述三种操作实现插入排序的时间复杂度最坏为( )。 {{ select(14) }}

  • Θ(𝑛2)Θ(𝑛^2)
  • Θ(n2logn)Θ(n^2 log n)
  • Θ(nlogn)Θ(n log n)
  • Θ(nlog2n)Θ(n log^2 n)

15.今年是 CCF(中国计算机学会)第( )次举办 CSP-J/S(计算机非专业级别的软件能力认证)? {{ select(15) }}

  • 27
  • 28
  • 5
  • 4

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

(1)

01 #include <iostream>
02 #include <cstring>
03 using namespace std;
04 string s, t;
05 string a, b;
06 int main() {
07	getline(cin, s);
08	getline(cin, a);
09	getline(cin, b);
10	for (int i = 0; i < s.size(); i ++) {
11		bool flag = true;
12		if (i + a.size() <= s.size()) {
13			for (int j = 0; j < a.size(); j ++) {
14				char p = s[i + j], q = a[j];
15				if ('a' <= p && p <= 'z') p = p - 'a' + 'A';
16				if ('a' <= q && q <= 'z') q = q - 'a' + 'A';
17				if (p != q)
18					flag = false;
19			}
20		} else
21			flag = false;
22
23		if (flag == true) {
24			t += b;
25			i += a.size() - 1;
26		} else
27			t += s[i];
28	}
29	cout << t << endl;
30	return 0;
31 }

保证输入的三行字符串的长度均不超过 𝟏𝟎𝟑𝟏𝟎^𝟑,且每个字符串均由 ASCII 可视字符或空格组成且非空。完成下面的判断题和单选题:

判断题

  1. 保持 s,b 的字母大小写不变,将 a 里的小写英文字母改写成大写、将大写英文字母改写成小写,输出结果不变。 ( ) {{ select(16) }}
  • 正确
  • 错误
  1. 每次调用 s.size()的复杂度是 O(1) 的,但若是把 s.size()替换成s.length() 则调用的复杂度将会变成 O(l),其中 l 是 s 当前的长度。这是因为s.length() 作为 strlen() 函数的 string 版本,会每次重新计算 s 最后一个元素的位置。 ( ) {{ select(17) }}
  • 正确
  • 错误
  1. 当输入的字符串 s,a,b 均由小写字母 a 或 b 组成,记 s,a,b 的长度分别为n,m,k,则程序的时间复杂度最坏为 O(nm+nk)。 ( ) {{ select(18) }}
  • 正确
  • 错误
  1. 当输入的字符串 s,a,b 均由小写字母 a 组成,记 s,a,b 的长度分别为 n,m,k且有 n>m>k,那么上述程序的总复杂度为 O(n)。 ( ) {{ select(19) }}
  • 正确
  • 错误

单选题

  1. 针对下列输入数据,程序的输出为?
National Olympiad in Informatics A154
A
C

{{ select(20) }}

  • National Olympiad in Informatics C154
  • NCtionCl OlympiCd in InformCtics C154
  • National!
  • Nctioncl Olympicd in Informctics C154
  1. 针对下列输入数据,程序的输出为?
abaabaaabaaaabaaaaabababab
aa
ab

{{ select(21) }}

  • abABbABBbABBBbABBBBbababab
  • ababbabbbabbbbabbbbbababab
  • ababbababababbabababababab
  • 程序陷入死循环/非正常退出,无法正常输出

(2)

01 #include<iostream>
02 using namespace std;
03 int a[100005], b[100005], n, m;
04 void very_quick_sort(int l, int r, int p, int q){
05    if(l >= r || p > q){ // ①
06        return;
07    }
08    int mid = (l + r) / 2;
09    int p0 = p - 1;
10    int q0 = q + 1;
11    for(int i = p;i <= q;i ++){
12       if(a[i] > mid) b[++ p0] = a[i];
13       else   b[-- q0] = a[i];
14    }
15    for(int i = p;i <= q;i ++)
16        a[i] = b[i];
17    very_quick_sort(mid + 1, r, p, p0);
18    very_quick_sort(l, mid, q0, q);
19 }
20 int main(){
21     cin >> n >> m;
22     for(int i = 1;i <= n;i ++)
23       cin >> a[i];
24     very_quick_sort(1, m, 1, n);
25        // ②
26     for(int i = 1;i <= n;i ++)
27        cout << a[i] << " ";
28     cout << endl;
29     return 0;
30 }	

保证输入的 nn不超过 10510^5mm 不超过10910^9,且𝟏𝒂𝟏,𝒂𝟐,,𝒂𝒏𝒎 𝟏 ≤ 𝒂_𝟏, 𝒂_𝟐, ⋯ , 𝒂_𝒏 ≤ 𝒎。完成下面的判断题和单选题

判断题

22.(1 分)上述代码实现了一种排序算法,可以将 a 数组按照从小到大的顺序排序。 {{ select(22) }}

  • 正确
  • 错误

23.如果在程序开始之前向 b 数组里写入数据(保证不会发生数组越界),则上述代码的输出不会发生变化。 ( )

{{ select(23) }}

  • 正确
  • 错误

24.若𝑛=𝑚 𝑛 = 𝑚,存在某种数据构造方式,使得上述代码运行的时间复杂度为𝑂(𝑛2) 𝑂(𝑛^2),这是因为算法本身是对快速排序的改进,但是这种改进不能避免由于对数组的划分不够均等而在极端数据下导致复杂度发生退化。 ( )

{{ select(24) }}

  • 正确
  • 错误

25.如果将 ① 处的 l >= r 条件删除(同时删除 || 使得程序能正常编译运行,下同),程序的时间复杂度不会发生变化;而将 p > q 条件删除,程序在某些数据下的运行效率将会明显降低。 ( )

{{ select(25) }}

  • 正确
  • 错误

单选题

26.不认为 𝑛, 𝑚 同阶,即可能出现 𝑛 远大于 𝑚 或者 𝑚 远大于 𝑛 的情况。则该程序的最坏时间复杂度为( ) 。 {{ select(26) }}

  • Θ(𝑛2+𝑚2)Θ(𝑛^2 + 𝑚^2)
  • Θ(mlogm)Θ(m log m)
  • Θ(mlogn)Θ(m log n)
  • Θ(nlogm)Θ(n log m)

27.若输入数据为:

10 10
10 4 5 2 2 3 1 5 8 3

那么在程序执行到 ② 位置时, b 数组 内的值为 ( )。

{{ select(27) }}

  • [10,8,3,5,1,3,2,2,5,4]
  • [3,5,1,3,2,2,5,4,10,8]
  • [10,8,5,5,4,3,3,2,2,1]
  • [1,2,2,3,3,4,5,5,8,10]

(3)

01 #include <iostream>
02 #include <vector>
03 #include <algorithm>
04 using namespace std;
05 const int mod = 1000000000 + 7;
06 int w0[100005];
07 int w1[100005];
08 int w2[100005];
09 int n, m, k, f[100005], d[100005], id[100005];
10 vector <int> e[100005];
11 void dfs(int u, int fa){
12     d[u] = d[fa] + 1;
13     f[u] = fa;
14
15     for(auto &v : e[u]) if(v != fa){
16       dfs(v, u);
17     }
18 }
19 bool cmp(int a, int b){
20     return d[a] < d[b];
21 }
22 int main(){
23    cin >> n >> m >> k;
24    for(int i = 2;i <= n;i ++){
25        int u, v;
26        cin >> u >> v;
27        e[u].push_back(v);
28        e[v].push_back(u);
29 }
30 dfs(1, 0); // ①
31 for(int i = 1;i <= m;i ++){
32     int x, w;
33     cin >> x >> w;
34     w1[x] = (w1[x] + w) % mod;
35     w2[x] = (w2[x] + w) % mod;
36 }
37 for(int i = 1;i <= n;i ++)
38     id[i] = i;
39 sort(id + 1, id + 1 + n, cmp);
40 for(int i = 1;i <= k;i ++){
41     for(int j = n;j >= 1;j --){
42         int x = id[j];
43         for(auto &y : e[x]) if(y != f[x]){
44            w1[y] = (w1[y] + w1[x]) % mod;
45         }
46         w1[x] = 0;
47      }
48      for(int x = 1;x <= n;x ++)
49         w1[x] = (w1[x] - w0[x] + mod) % mod,
50         w0[x] = 0;
51      for(int j = 1;j <= n;j ++){ // ②
52          int x = id[j];
53          if(f[x]){
54              w1[f[x]] = (w1[f[x]] + w2[x]) % mod;
55              w2[f[x]] = (w2[f[x]] + w2[x]) % mod;
56 				w0[x] = (w0[x] + w2[x]) % mod;
57 				w2[x] = 0;
58 			}
59 		}
60  }
61  for(int i = 1;i <= n;i ++)
62      cout << w1[i] << " ";
63 return 0;
64 }

保证输入的 n,mn,m 不超过 10510^5k k 不超过 20,且 1xin0wi<109+71≤x_i≤n, 0≤w_i<10^9+7。 完成下面的判断题和单选题:

判断题

28.如果更改 ① 处 dfs(1, 0) 为 dfs(n, 0),则输出结果可能有变化。 ( ) {{ select(28) }}

  • 正确
  • 错误

29.(1 分) 如果 k=n,那么输出结果均为 0。 ( ) {{ select(29) }}

  • 正确
  • 错误

30.如果更改 ② 处 for(int j=1;j< n;j++) 为 for(int j=n;j>=1;j--),那么对于任意合法的输入数据,更改前后程序的输出均相同。 ( ) {{ select(30) }}

  • 正确
  • 错误

单选题

31.(2 分) 该程序的时间复杂度为( ) 。 {{ select(31) }}

  • (nmk)(nmk)
  • (nk+m)(nk+m)
  • Θ(km+n)Θ(km+n)
  • Θ(n+m+2k)Θ(n+m+2^k)

32.对于以下的输入数据,输出结果为 ( ) 。

5 2 1
1 2
2 3
3 4
3 5
1 5
3 2

{{ select(32) }}

  • 0 7 0 2 2
  • 2 7 2 3 2
  • 5 2 1 1 1
  • 0 2 1 1 2

33.对于以下的输入数据,输出结果为 ( ) 。

9 9 2
1 2
1 7
2 3
2 4
7 8
4 5
4 6
8 9
1 1
2 10
3 100
4 1000
5 10000
6 100000
7 1000000
8 10000000
9 100000000

{{ select(33) }}

  • 10001100 1110000 1001 101 100010 10010 100000010 1 1000000
  • 0 0 1 1 10 10 0 1 1000000
  • 11001110 1111100 1001 110101 100010 10010 110000010 100000001 1000000
  • 11001111 1111112 1121 111121 112010 112010 111000012 112000001 121000000

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

(1)(序列问题) 给定序列 ana_n,求有多少对 (i,j) 满足 ai<aja_i<a_j。 测试数据满足n106ai109n≤10^6, a_i≤10^9

提示: 对于任意的 aiaja_i≠ a_j,可以发现 (i,j) 或 (j,i) 能对答案产生 1 的贡献,因此我们只需要用总的对数减去 ai=aj(i,j)a_i=a_j 的 (i,j) 数量,就能得到答案。

试补全程序。

01 #include<bits/stdc++.h>
02 using namespace std;
03 const int Maxn = ①;
04 int n, a[Maxn];
05 long long s[Maxn], ans;
06 bool check(int l, int r) {
07 		if (s[r] - s[l - 1] == ②) return true;
08 		return false;
09 }
10
11
12
13 int main() {
14 		cin >> n;
15 		for (int i = 1; i <= n; i ++)
16 			cin >> a[i];
17 		sort (a + 1, a + n + 1);
18 		for (int i = 1; i <= n; i ++)
19 			s[i] = s[i - 1] + a[i];
20 		ans = ③;
21 		for (int i = 1; i <= n;) {
22 			int l = i, r = n, pos = n;
23 			while (④) {
24 				int mid = (l + r) >> 1;
25 				if(check(l, mid))
26 					l = mid + 1, pos = mid;
27 				else
28 					r = mid - 1;
29 			}
30 			ans -= ⑤;
31 			i = pos + 1;
32 		}
33 		cout << ans;
34 }

34.① 处应填( ) 。 {{ select(34) }}

  • 1e6 + 7
  • 1000000
  • 1e6
  • 1000000000000

35.② 处应填( ) 。 {{ select(35) }}

  • (r - l + 1) * a[l]
  • s[r] - s[l - 1]
  • 1LL * (r–l+1) * a[l]
  • a[1] = 0

36.③ 处应填( ) 。 {{ select(36) }}

  • n * (n + 1) / 2
  • 1ll * n * (n + 1) / 2
  • n * (n - 1) / 2
  • 1ll * n * (n - 1) / 2

37.④ 处应填( ) 。 {{ select(37) }}

  • l < r
  • l <= r
  • l <= r + 1
  • l > r

38.⑤ 处应填( ) 。 {{ select(38) }}

  • (pos - l + 1) * (pos - l) / 2
  • 1ll * (pos - l + 1) * (pos - l) / 2
  • (pos - i + 1) * (pos - i) / 2
  • 1ll * (pos - i + 1) * (pos - i) / 2

(2)(异或和) 给定序列an a_n,求其所有子区间异或和的和。某个区间的异或和的意思是将这个区间内的所有数字分别进行异或计算。其中n1050ai109 n≤10^5, 0≤a_i≤10^9

提示:对每一位独立计算,对右端点扫描线,并用异或前缀和辅助统计。

试补全程序。

01 #include<bits/stdc++.h>
02 using namespace std;
03 const int N = 1e5 + 7;
04 int n, a[N], cnt[2];
05 long long ans;
06 int main () {
07 		cin >> n;
08 		for (int i = 1; i <= n; i ++)
09 			cin >> a[i], ①;
10 		for (int bit = ②; ③; bit --) {
11 			cnt[0] = cnt[1] = 0;
12 			for (int i = 0; i <= n; i ++) {
13 				cnt[④] ++;
14 				ans += 1LL* ⑤;
15 			}
16 		} cout << ans;
17 }

39.① 处应填( ) 。 {{ select(39) }}

  • a[i - 1] ^= a[i]
  • a[i] ^= a[i - 1]
  • a[i - 1] += a[i]
  • a[i] += a[i - 1]

40.② 处应填( ) 。 {{ select(40) }}

  • n - 1
  • 29
  • n
  • n + 1

41.③ 处应填( ) 。 {{ select(41) }}

  • bit
  • bit >= n
  • bit - 1
  • ~bit

42.④ 处应填( ) 。 {{ select(42) }}

  • (a[i] >> bit) & 1
  • a[i] & (1 << bit)
  • a[i] & (1LL << bit)
  • (a[i] >> bit) ^ 1

43.⑤ 处应填( ) 。 {{ select(43) }}

  • cnt[(a[i] >> bit) & 1] << i
  • cnt[(a[i] >> bit) & 1 ^ 1] << bit
  • cnt[(a[i] >> bit) & 1] << bit
  • cnt[(a[i] >> bit) & 1 ^ 1] << i