CSP-J 初赛模拟卷(第 07 套)
入门级 C++ 语言试题
---
#### **一、单项选择题(共 15 题,每题 2 分,共计 30 分)**
( ) 1. 计算机应用的最早领域( )
A. 数值计算 B. 人工智能 C. 机器人 D. 过程控制
( ) 2. 二进制数11 1011 1001 0111和01 0110 1110 1011进行逻辑与运算的结果是( )。
A. 01 0010 1000 1011 B. 01 0010 1001 0011
C. 01 0010 1000 0001 D. 01 0010 1000 0011
( ) 3. 在内存储器中每个存储单元都被赋予一个唯一的序号,称为( )
A. 地址 B. 序号 C. 下标 D. 编号
( ) 4. 如果开始时计算机处于小写输入状态,现在有一只小老鼠反复按照CapsLock、 字母键A、字母键 S、字母键D、字母键 F 的顺序循环按键,即 CapsLock、A、 S、D、F、CapsLock、A、S、D、F、……,屏幕上输出的第 81 个字符是字母( )。
A. A B. S C. D D. a
( ) 5. 分辨率为 800x600、16 位色的位图,存储图像信息所需的空间为( )。
A. 937.5KB B. 4218.75KB C. 4320KB D. 2880KB
( ) 6. 以比较作为基本运算,在N个数中找出最大数,最坏情况下所需要的最少的比较次数为( )。
A. $N^2$ B. N C. N-1 D. `N+1`
( ) 7. 以下是 32 位机器和 64 位机器的区别是( )。
A. 显示器不同 B. 硬盘大小不同 C. 寻址空间不同 D. 输入法不同
( ) 8. 由四个没有区别的点构成的简单无向连通图的个数是( )。
A. 6 B. 7 C. 8 D. 9
( ) 9. 言泡排序算法的伪代码如下:
```text
输入:数组L,n≥k。输出:按非递减顺序排序的L。
算法 BubbleSort:
1. FLAG ← n //标记被交换的最后元素位置
2. while FLAG > 1 do
3. k ← FLAG -1
4. FLAG ← 1
5. for j=1 to k do
6. if L(j) > L(j+1) then do
7. L(j) ← L(j+1)
8. FLAG ← j
```
对 $n$ 个数用以上音泡排序算法进行排序,最少需要比较多少次?( )。
A. $n^2$ B. $n - 2$ C. $n - 1$ D. $n$
( ) 10. 表达式a\*(b+c)\*d 的后缀表达式为( ),其中“\*”和“+”是运算符。
A. `**a+bcd` B. `abc+*d*` C. `abc+d**` D. `*a*+bcd`
( ) 11. 一棵二叉例如右图所示,若采用顺序存储结构,即用一维数组元素存储该二叉树中的结点(根结点的下标为1, 若某结点的下标为i,则其在孩子位于下标2i处、右孩子位于下标2i+1处),则该数组的最大下标至少为( )。
A. 6 B. 10 C. 15 D. 12
( ) 12. 十进制小数 13.375 对应的二进制数是( )。
A. 1101.011 B. 1011.011 C. 1101.101 D. 1010.01
( ) 13. 一些数字可以颠倒过来看,例如0、1、8颠倒过来还是本身,6颠倒过来是9, 9颠倒过来看还是6,其他数字颠倒过来都不构成数字。
类似的,一些多位数也可以颠倒过来看,比如106颠倒过来是901。假设某个城市的车牌只由5位数字组成,每一位都可以取0到9。
请问这个城市最多有多少个车牌倒过来恰好还是原来的车牌?( )
A. 60 B. 125 C. 75 D. 100
( ) 14. 为了统计一个非负整数的二进制形式中 1 的个数,代码如下:
int CountBit(int x)
{
int ret = 0;
while (x)
{
ret++;
___________;
}
return ret;
}
则空格内要填入的语句是( )。
A. `x >>= 1` B. `x &= x - 1` C. `x |= x >> 1` D. `x <<= 1`
( ) 15. 下列说法正确的是( )。
A. CPU的主要任务是执行数据运算和程序控制
B. 存储器具有记忆能力,其中信息任何时候都不会丢失
C. 两个显示器屏幕尺寸相同,则它们的分辨率必定相同
D. 个人用户只能使用 Wifi 的方式连接到 Internet
---
#### **二、阅读程序(程序输入不超过数组或字符串定义的范围,判断题正确填 √,错误填 ×;共 18 小题,共计 39 分,各小题分值见题目)**
**(1)**
```cpp
1 #include
2 using namespace std;
3 int n;
4 int a[100];
5
6 int main() {
7 scanf("%d", &n);
8 for (int i = 1; i <= n; ++i)
9 scanf("%d", &a[i]);
10 int ans = 1;
11 for (int i = 1; i <= n; ++i) {
12 if (i > 1 && a[i] < a[i - 1])
13 ans = i;
14 while (ans < n && a[i] >= a[ans + 1])
15 ++ans;
16 printf("%d\n", ans);
17 }
18 return 0;
19 }
```
**判断题**
( ) 16. (1分) 第16行输出ans时,ans的值一定大于i。( )
( ) 17. (1分) 程序输出的ans小于等于n。( )
( ) 18. (1.5分) 若将第12行的 $<$ 改为 $!=$ ,程序输出的结果不会改变。( )
( ) 19. (1.5分) 当程序执行到第16行时,若ans-i>2,则 $a[i+1]\leq a[i]$ 。( )
**单选题**
( ) 20. (3分) 若输入的a数组是一个严格单调递增的数列,此程序的时间复杂度( )
A. `O(log n)` B. `O(n^2)` C. `O(n log n)` D. `O(n)`
( ) 21. (4分) 最坏情况下,此程序的时间复杂度是( )
A. `O(n^2)` B. `O(log n)` C. `O(n)` D. `O(n log n)`
**(2)**
```cpp
1 #include
2 #include
3
4 char base[64];
5 char table[256];
6 char str[256];
7 char ans[256];
8
9 void init()
10 {
11 for (int i = 0; i < 26; i++) base[i] = 'A' + i;
12 for (int i = 0; i < 26; i++) base[26 + i] = 'a' + i;
13 for (int i = 0; i < 10; i++) base[52 + i] = '0' + i;
14 base[62] = '+', base[63] = '/';
15
16 for (int i = 0; i < 256; i++) table[i] = 0xff;
17 for (int i = 0; i < 64; i++) table[base[i]] = i;
18 table['='] = 0;
19 }
20
21 void decode(char *str)
22 {
23 char *ret = ans;
24 int i, len = strlen(str);
25 for (i = 0; i < len; i += 4) {
26 (*ret++) = table[str[i]] << 2 | table[str[i + 1]] >> 4;
27 if (str[i + 2] != '=')
28 (*ret++) = (table[str[i + 1]] & 0x0f) << 4 | table[str[i + 2]] >> 2;
29 if(str[i + 3] != '=')
30 (*ret++) = table[str[i + 2]] << 6 | table[str[i + 3]];
31 }
32 }
33
34 int main()
35 {
36 init();
37 printf("%d\n", (int)table[0]);
38
39 scanf("%s", str);
40 decode(str);
41 printf("%s\n", ans);
42 return 0;
43 }
```
假设 `char` 是 8 位有符号类型,输入字符串长度为 4 的倍数,且输入不超过数组范围。
**判断题**
( ) 22. (1.5分) 输出的第二行一定是由小写字母、大写字母、数字和 `+`、`/`、`=` 构成的字符串。( )
( ) 23. (1.5分) 可能存在输入不同,但输出的第二行相同的情形。( )
( ) 24. (1.5分) 输出的第一行为 `-1`。( )
**单选题**
( ) 25. (3分) 设输入字符串长度为 $n$,`decode` 函数的时间复杂度为( )。
A. $O(\sqrt n)$ B. $O(n)$ C. $O(n\log n)$ D. $O(n^2)$
( ) 26. (3分) 当输入为 `Y3Nx` 时,输出的第二行为( )。
A. `csp` B. `csq` C. `CSP` D. `Csp`
( ) 27. (3.5分) 当输入为 `Y2NmIDIwMjE=` 时,输出的第二行为( )。
A. `ccf2021` B. `ccf2022` C. `ccf 2021` D. `ccf 2022`
**(3)**
```cpp
1 #include
2 #include
3 using namespace std;
4 int n, m;
5 int f[101][101];
6 int F[101][101];
7 int main(){
8 scanf("%d%d",&n,&m);//n的值在1到100之间
9 memset(f,-1,sizeof(f));
10 for(int i = 1; i <= m; i++) {
11 int u,v,w;//w的值在0到10000之间
12 scanf("%d%d%d",&u,&v,&w);
13 f[u][v]=f[v][u]=w;
14 }
15 for(int k = 1; k <= n; k++)
16 for(int i=1;i <=n; i++)
17 for(int j=1;j<= n; j++)
18 if(f[i][k]!=-1&&f[k][j]!=-1)
19 if(f[i][j]==-1||f[i][j]>f[k][j]+f[i][k])
20 f[i][j]=f[i][k]+f[k][j];
21 int ans=2147483647;
22 for(int i=1;i<=n;i++)
23 for(int j=1;j<=n; j++){
24 for(int x=1;x<=n; x++)
25 for(int y=1;y<=n; y++)
26 F[x][y]=f[x][y];
27 F[i][j]=F[j][i]=0;
28 for(int x=1;x<= n; x++)
29 for(int y=1;y<=n; y++)
30 if(F[x][y]==-1||F[x][y]>F[x][i]+F[i][y])
31 F[x][y]=F[x][i]+F[i][y];
32 for(int x=1;x<=n; x++)
33 for(int y=1;y<=n; y++)
34 if(F[x][y]==-1||F[x][y]>F[x][j]+F[j][y])
35 F[x][y]=F[x][j]+F[j][y];
36 int res=0;
37 for(int x=1;x<=n; x++)
38 for(int y=1;y
2 #include
3 using namespace std;
4 const int maxn = 10000000;
5 const int maxs = 10000;
6
7 int n;
8 unsigned a[maxn], b[maxn],res[maxn], ord[maxn];
9 unsigned cnt[maxs + 1];
10 int main() {
11 scanf("%d", &n);
12 for (int i = 0; i < n; ++i)
13 scanf("%u%u", &a[i], &b[i]);
14 memset(cnt, 0, sizeof(cnt));
15 for (int i = 0; i < n; ++i)
16 __(1)__; // 利用 cnt 数组统计数量
17 for (int i = 0; i < maxs; ++i)
18 cnt[i + 1] += cnt[i];
19 for (int i = 0; i < n; ++i)
20 __(2)__; // 记录初步排序结果
21 memset(cnt, 0, sizeof(cnt));
22 for (int i = 0; i < n; ++i)
23 __(3)__; // 利用 cnt 数组统计数量
24 for (int i = 0; i < maxs; ++i)
25 cnt[i + 1] += cnt[i];
26 for (int i = n - 1; i >= 0; --i)
27 __(4)__; // 记录最终排序结果
28 for (int i = 0; i < n; i++)
29 printf("%u %u\n", __(5)__);
30
31 return 0;
32 }
```
( ) 34. (3分) (1)处应填
A. `++cnt [i]` B. `++cnt[b[i]]`
C. `++cnt[a[i] * maxs + b[i]]` D. `++cnt[a[i]]`
( ) 35. (3分) (2)处应填
A. `ord[--cnt[a[i]]] = i` B. `ord[--cnt[b[i]]] = a[i]`
C. `ord[--cnt[a[i]]] = b[i]` D. `ord[--cnt[b[i]]] = i`
( ) 36. (3分) (3)处应填
A. `++cnt[b[i]]` B. `++cnt[a[i] * maxs + b[i]]`
C. `++cnt[a[i]]` D. `++cnt[i]`
( ) 37. (3分) (4)处应填
A. `res[--cnt[a[ord[i]]]] = ord[i]` B. `res[--cnt[b[ord[i]]]] = ord[i]`
C. `res[--cnt[b[i]]] = ord[i]` D. `res[--cnt[a[i]]] = ord[i]`
( ) 38. (3分) (5)处应填
A. `a[i], b[i]` B. `a[res[i]], b[res[i]]`
C. `a[ord[res[i]]], b[ord[res[i]]]` D. `a[res[ord[i]]], b[res[ord[i]]]`
**(2)**
完善程序
(郊游活动)有n名同学参加学校组织的郊游活动,已知学校给这n名同学的郊游总结题为A元,与此同时第i位同学自己携带了M元。为了方便郊游,活动地点提供 $B(\geq n)$ 钢游行车供人租用,租用第j辆自行车的价格为C1元,每位同学可以使用自己携带的钱或者学校的郊游经验,为了方便账务管理,每位同学只能为自己租用自行车,且不会借钱给他人,他们供图道最多有多少位同学能够租用到自行车。
本题采用二分法。对于区间 $[l, r]$ ,我们取中间点 mid 并判断租用到自行车的人数能否达到 mid。判断的过程是利用贪心算法实现的。
```cpp
1 #include
2 using namespace std;
3 #define MAXN 1000000
4 int n, B, A, M[MAXN], C[MAXN], l, r, ans, mid;
5 bool check(int nn) {
6 int count = 0, i, j;
7 i = __(1)__;
8 j = 1;
9 while (i <= n) {
10 if(__(2)__)
11 count += C[j] - M[i];
12 i++;
13 j++;
14 }
15 return __(3)__;
16 }
17 void sort(int a[], int l, int r) {
18 int i = l, j = r, x = a[(l + r) / 2], y;
19 while (i <= j) {
20 while (a[i] < x) i++;
21 while (a[j] > x) j--;
22 if (i <= j) {
23 y = a[i]; a[i] = a[j]; a[j] = y;
24 i++; j--;
25 }
26 }
27 if (i < r) sort(a, i, r);
28 if (l < j) sort(a, l, j);
29 }
30 int main() {
31 int i;
32 cin >> n >> B >> A;
33 for (i = 1; i <= n; i++)
34 cin >> M[i];
35 for (i = 1; i <= B; i++)
36 cin >> C[i];
37 sort(M, 1, n);
38 sort(C, 1, B);
39 l = 0;
40 r = n;
41 while (l <= r) {
42 mid = (l + r) / 2;
43 if(__(4)__){
44 ans = mid;
45 l = mid + 1;
46 }else
47 r = __(5)__;
48 }
49 cout << ans << endl;
50 return 0;
51 }
```
( ) 39. (3分) (1)处应填:________________
( ) 40. (3分) (2)处应填:________________
( ) 41. (3分) (3)处应填:________________
( ) 42. (2.5分) (4)处应填:________________
( ) 43. (2.5分) (5)处应填:________________