Files
cpp-courseware/2.Course/5.C++_Exam/NOI/CSP-J 初赛模拟卷/试题/CSP-J初赛模拟卷·第17套.md
T
xiaolinquan 0af92a68d9 整理 NOI 初赛资料目录并标准化 CSP-J 模拟卷
- 将18套模拟卷分离为试题和答案解析,补齐并规范逐题解析
- 补充SVG图示,统一试题排版并导出打印PDF
- 重整初赛专题训练与复习资料目录,清理旧版源文件
2026-11-06 17:50:51 +08:00

13 KiB
Raw Blame History

CSP-J 初赛模拟卷(第 17 套)
入门级 C++ 语言试题

一、单项选择题(共 15 题,每题 2 分,共计 30 分)

( ) 1. 十进制数 114 的相反数的8位二进制补码是:
A. 10001110  B. 10001101  C. 01110010  D. 01110011

( ) 2. 以下哪个网站不是 Online Judge(在线程序判题系统)?Online Judge 可以查看算法题目,提交自己编写的程序,然后可以获得评测机反馈的结果。
A. Luogu  B. Gitee  C. LeetCode  D. Codeforces

( ) 3. 小A用字母A表示1,B表示2,以此来推,用 Z 表示 26。对于27以上的数,可以用两位或者更长的字符串来对应,例如AA对应27,AB 对应 28,AZ 对应52,AAA 对应703……那么BYT 字符串对应的数字是什么?
A. 2018  B. 2020  C. 2022  D. 2024

( ) 4. UIM 拍摄了一张照片,其分辨率是 4096× 2160,每一个像素都是 24位真彩色。在没有压缩的情况下,这张图片占用空间接近以下哪个值?
A. 8MB  B. 25MB  C. 200MB  D. 200KB

( ) 5. 在一个长度为n的数组中找到第k大的数字,平均的算法时间复杂度最低的是
A. O (n)  B. O (nk)  C. O (nlogn)  D. O (n^2)

( ) 6. 对于“树”这种数据结构,正确的有: ①一个有n个顶点、n-1 条边的图是树 ②一个树中的两个顶点之间有且只有一条简单路径 ③树中一定存在度数不大于 1的顶点 ④树可能存在环
A. ①②④  B. ①②③  C. ②③  D. ①②

( ) 7. 博艾中学进行了一次信息学会考测试,其优、良、及格、不及格的试卷数量分别为10、13、14、5张。现在这些卷子混在一起,要将这些卷子按照等级分为4叠。分卷子的方法是,每次将一叠有不同等级答卷的卷子分为两堆,使得这两堆中没有相同等级的卷子,然后可以再分,直到分为4叠。要分完这些卷子,至少需要多少次“分卷子”的操作? 将一堆数量为n的卷子分成两堆,就会产生n次分卷子的操作。
A. 84  B. 93  C. 78  D. 85

( ) 8. 一个二叉树的前序遍历是HGBDAFEC,中遍历是BGHFAEDC,同时采用顺序存储结构,即用一维数组元素存储该二叉树中的结点(根结点的下标为1,若某结点的下标为i,则其左孩子位于下标2i处、右孩子位于下标2i+1处),则该数组的最大下标至少为( )
A. 7  B. 13  C. 15  D. 12

( ) 9. 在C++语言中,如果a=1;b=0;c=1;那么以下表达式中为1的是:
A. a&&b||b&&c  B. a+b>c||b  C. !(!c&&(!a||b))  D. a+b+c

( ) 10. 在一个初始长度为n的链表中连续进行k次操作,每次操作是读入两个数字a_i和b_i,在链表中找到元素为a_i的结点(假设一定可以找到),然后将这b_i个元素插入到这个结点前面。在最理想的情况下,链表访问的结点数量最少可能是多少(不算将要插入的结点)?
A. n次  B. k次  C. nk次  D. n+k次

( ) 11. A班有5名风纪委员,B班有4名风纪委员,C班有3名风纪委员。现在需要这些同学中选取6名风纪委员巡逻,如果只关注各班派出的风纪委员人数,有几种不同的方案?
A. 9  B. 12  C. 15  D. 18

( ) 12. 以下哪种排序算法的时间复杂度是O(n^2)?
A. 计数排序  B. 插入排序  C. 希尔排序  D. 归并排序

( ) 13. 已知rand()可以生成一个0到32767的随机整数,如果希望得到一个范围在[a,b)的随机整数,a和b均是不超过100的正整数且a<b,那么可行的表达式是什么?
A. (rand()%(b-a))+a  B. (rand()%(b-a+1))+a
C. (rand()%(b-a))+a+1  D. (rand()%(b-a+1))+a+1

( ) 14. 一个7个顶点的完全图需要至少删掉多少条边才能变为森林?
A. 16  B. 21  C. 15  D. 6

( ) 15. 2020年8月,第( )届全国青少年信息学奥林匹克竞赛在( )举行?
A. 26, 广州  B. 26, 长沙  C. 37, 广州  D. 37, 长沙


二、阅读程序(程序输入不超过数组或字符串定义的范围,判断题正确填 √,错误填 ×;共 18 小题,共计 40 分,各小题分值见题目)

(1)

 1  #include<iostream>
 2  using namespace std;
 3  #define MAXN 20
 4  int gu[MAXN][MAXN];
 5  int luo(int n, int m) {
 6      if(n <= 1 || m < 2)
 7          return 1;
 8      if(gu[n][m] != -1)
 9          return gu[n][m];
10      int ans=0;
11      for(int i = 0; i <m; i += 2)
12          ans+=luo(n-1, i);
13      gu[n][m] = ans;
14      return ans;
15  }
16  int main() {
17      int n, m;
18      cin >> n >> m;
19      for(int i = 0; i < MAXN; i++)
20          for(int j = 0; j < MAXN; j++)
21              gu[i][j]= -1;
22      cout << luo(n, m);
23      return 0;
24  }

判断题

( ) 16. (1分) luo函数中,m的值不可能是奇数。( )

( ) 17. (1分) 若将第11行的“<”改为“<=”,程序的输出结果可能会改变。( )

( ) 18. (2分) 若将第8、9、13行删除,程序的运行的结果不变。( )

( ) 19. (2分) 在添加合适的头文件后,将第19 到 21 行替换为“memset(gu, 255,sizeof(gu));”可以起到相同的作用。( )

单选题

( ) 20. (4分) 若输入数据为 4 8,则输出为( )。
A. 7  B. 8  C. 15  D. 16

( ) 21. (3分) 最坏情况下,此程序的时间复杂度是( )。
A. $O(m^2n)$  B. $O(mn!)$  C. $O(n^2)$  D. O(n^2m)

(2)

 1  #include<cstdio>
 2  #include<cstring>
 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<x; y++)
39                      res +=F[x][y];
40              ans = res < ans ? res : ans;
41          }
42      printf("%d\n",ans);
43      return 0;
44  }

判断题

( ) 22. (1分) 14到16行,将外层到内层的循环变量依次调整为i、j、k,程序的运行的结果不变。( )

( ) 23. (2分) 这个程序的时间复杂度和m无关。( )

( ) 24. (2分) 20行的ans如果初始化为10^7时,可能无法得到正确结果。( )

( ) 25. (2分) 若将第27到30行的部分和31到34行的两个部分互换,程序的运行的结果不变。( )

单选题

( ) 26. (3分) 若输入数据为4 5/1 2 3/1 3 6/2 3 4/2 4 7/3 4 2(其中“/”为换行符),则输出为( )。
A. 14  B. 18  C. 21  D. 28

( ) 27. (3分) 这个程序使用了( )算法。
A. Floyd  B. Dijkstra  C. Prim  D. Kruskal

(3)

 1  #include<bits/stdc++.h>
 2  using namespace std;
 3  #define MOD 19260817
 4  #define MAXN 1005
 5  long long A[MAXN][MAXN]={0},sum[MAXN][MAXN]={0};
 6  int n, m, q;
 7  int main(){
 8      A[1][1]=A[1][0]=1;
 9      for(int i=2;i <= 1000; i++) {
10          A[i][0]=1;
11          for(int j = 1; j <= i; j++)
12              A[i][j]=(A[i-1][j]+A[i-1][j-1])%MOD;
13      }
14      for(int i =1;i <= 1000; i++)
15          for(int j=1;j<=1000;j++)
16              sum[i][j]=(sum[i-1][j]+sum[i][j-1]
17              -sum[i-1][j-1]+A[i][j]+MOD)%MOD;
18              int q;
19      cin >> q;
20      while(q--){
21          int n, m;
22          cin >> n >> m;
23          cout << sum[n][m] << endl;
24      }
25      return 0;
26  }

判断题

( ) 28. (1分) 当i<=j时,A[i][i]的值是0。( )

( ) 29. (2分) 当i>j时,A[i][j]的值相当于从i个不同元素中取出j个元素的排列数。( )

( ) 30. (2分) sum[i][j]的值(1<j<i≤1000)不小于sum[i-1][j-1]的值。( )

( ) 31. (2分) 若将第12行改为“A[i][j]=(A[i-1][j]+A[i-1][j-1]+MOD)%MOD;”,程序的运行的结果不变。( )

单选题

( ) 32. (4分) A[i][j](1≤i≤10,1≤j≤10)的所有元素中,最大值是( )。
A. 126  B. 276  C. 252  D. 210

( ) 33. (3分) 若输入数据为1/5 3(其中“/”为换行符),则输出为( )。
A. 10  B. 35  C. 50  D. 24


三、完善程序(程序输入不超过数组或字符串定义的范围;共 10 小题,共计 30 分,各小题分值见题目)

(1)

(封禁xxs)现有n个xxs(编号为1到n),每个xxs都有一个关注者,第i个xxs的关注者是a_i。现在管理员要将其中的一些xxs的账号封禁,但需要注意的是如果封禁了第i个人,那么为了不打草惊蛇,就不能封禁他的关注者a_i。现在想知道最多可以封禁多少个xxs。 输入第一行是一个不超过300000的整数n,第二行是n个1到n的整数表示。 输出一行,一个整数表示答案。

 1  #include<cstdio>
 2  using namespace std;
 3  #define MAXN 300005
 4  int n, ans=0, a[MAXN], in[MAXN]={0};
 5  bool vis[MAXN]={0};
 6  void dfs(int cur, int w){
 7      if(vis[cur])
 8          return;
 9      vis[cur]=true;
10      if(w==1) ans++;
11      __(1)__
12      if(__(2)__)
13          dfs(a[cur], __(3)__);
14  }
15  int main(){
16      scanf("%d",&n);
17      for(int i=1;i <=n; i++) {
18          scanf("%d", &a[i]);
19          in[a[i]]++;
20      }
21      for(int i=1;i <= n; i++)
22          if(!in[i]) __(4)__;
23      for(int i=1;i<=n; i++)
24          if(__(5)__) dfs(i,0);
25      printf("%d\n",ans);
26      return 0;
27  }

( ) 34. (3分) (1)处应填
A. a[cur]=cur;  B. in[a[cur]]=0;  C. in[a[cur]]--;  D. in[cur]--;

( ) 35. (3分) (2)处应填
A. in[a[cur]] != 0 || w == 1  B. in[a[cur]]==0||w==0
C. in[a[cur]]!=0||w==0  D. in[a[cur]]==0||w==1

( ) 36. (3分) (3)处应填
A. 0  B. 1  C. w  D. 1-w

( ) 37. (3分) (4)处应填
A. dfs(i,1)  B. dfs(i,0)  C. dfs(a[i], 1)  D. dfs(a[i], 0)

( ) 38. (3分) (5)处应填
A. !in[i]  B. in[i]  C. !vis[i]  D. vis[I]

(2)

(烧作业)某课作业布置了N(3≤N≤10000)个题目,第i题对应的得分是a。作业的总得分的计算方式为去掉作业中得分最小的一个题,剩下其它所有题目得分的平均值。但很不幸小A遇到了一场火灾,前K(1<K<N-2)个题目被烧了,无法记录得分。小A想知道,K是多少时,可以得到最高的作业得分?作业被烧了前K页,这时的得分是从第K+1页到最后一页中,去除最小得分后取平均值。 输入第一行是整数N,第二行是n个不超过10000的非负整数表示a 输出一行,若干个整数表示答案。如果有多个K,请依次升序输出。

 1  #include<cstdio>
 2  #include<cmath>
 3  #define min(a,b)(a<b?a:b)
 4  #define MAXN 100002
 5  using namespace std;
 6  int n, k[MAXN], cnt=0;
 7  int s[MAXN], minScore, sum;
 8  double maxAverage=0,nowAverage;
 9  int main() {
10      scanf("%d",&n);
11      for(int i=1;i<= n;i++)
12          scanf("%d",&s[i]);
13      minScore=s[n];
14      __(1)__;
15      for(int i=n-1;i>=2;i--) {
16          minScore=min(minScore,s[i]);
17              __(2)__;
18          nowAverage=__(3)__;
19          if(nowAverage> maxAverage){
20              __(4)__
21                  maxAverage=nowAverage;
22          } else if(fabs(nowAverage-maxAverage)<1e-6)
23              __(5)__;
24      }
25      for(int i=cnt; i >= 1; i--)
26          printf("%d\n",k[i]);
27      return 0;
28  }

( ) 39. (3分) (1)处应填
A. sum=n  B. sum=s[1]  C. sum=s[n]  D. sum=0

( ) 40. (3分) (2)处应填
A. sum=maxAverage*(n-i)  B. sum+=s[i]
C. sum+=s[n-i]  D. sum=s[i]+minScore

( ) 41. (3分) (3)处应填
A. (double)(sum+minScore)/(n-i)  B. sum*1.0/(n-i)
C. (int)(sum-minScore)/(n-i)  D. (double)(sum-minScore)/(n-i)

( ) 42. (3分) (4)处应填
A. k[++cnt]=i;  B. k[cnt++]=i-1
C. cnt=1;k[cnt]=i-1;  D. cnt=0;k[cnt]=I;

( ) 43. (3分) (5)处应填
A. k[cnt++]=i;  B. k[++cnt]=i-1;  C. k[cnt++] =n-i;  D. k[cnt]=i;