Files
cpp-courseware/2.Course/5.C++_Exam/NOI/CSP-J 初赛模拟卷/试题/CSP-J初赛模拟卷·第08套.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 初赛模拟卷(第 08 套)
入门级 C++ 语言试题

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

( ) 1. 以下不属于无线通信技术的是( )。
A. 蓝牙  B. Wifi  C. GPRS  D. 以太网

( ) 2. 在 8 位二进制补码中,10101011 表示的数是十进制下的( )。
A. 43  B. -85  C. -43  D. -84

( ) 3. 以下不是存储设备的是( )。
A. 光盘  B. 磁盘  C. 固态硬盘  D. 鼠标

( ) 4. 编译器的主要功能( )
A. 将源程序翻译成机器指令代码  B. 将源程序重新组合
C. 将低级语言翻译成高级语言  D. 将一种高级语言翻译成另一种高级语言

( ) 5. 若有如下程序段,其中s、a、b、c均已定义为整型变量,且a、c均已赋值(c大于0)


\begin{array}{l} \text {s = a ;} \\ \text {for(b = 1;b< = c;b++)} \\ \text {s = s - 1 ;} \end{array}

则与上述程序段功能等价的赋值语句是( )
A. s = a - c;  B. s = a - b;  C. s=s-c;  D. s=b-c;

( ) 6. 给定一个含 N 个不相同数字的数组,在最坏情况下,找出其中最大或最小的数,至少需要 N - 1 次比较操作。则最坏情况下,在该数组中同时找最大与最小的数至少需要( )次比较操作。([表示向上取整,]表示向下取整)
A. $\lceil 3N / 2\rceil -2$  B. $\lfloor 3N / 2\rfloor -2$  C. $2N - 2$  D. 2N - 4

( ) 7. 由1, 1, 2, 2, 3这五个数字组成不同的三位数有( )种。
A. 18  B. 15  C. 12  D. 24

( ) 8. 向一个栈顶指针为 hs 的链式栈中插入一个指针s 指向的结点时,应执行( )。
A. hs->next = s;  B. s->next = hs; hs = s;
C. s->next = hs->next; hs->next = s;  D. s->next = hs; hs = hs->next;

( ) 9. 对于有n个顶点、m条边的无向联通图(m>n),需要删掉( )条边才能使其成为一棵树。
A. n-1  B. m-n  C. m-n-1  D. m-n+1

( ) 10. 把8个同样的球放在5个同样的袋子里,允许有的袋子空着不放,问共有多少种不同的分法?( ) 提示:如果8个球都放在一个袋子里,无论是哪个袋子,都只算同一种分法。
A. 22  B. 24  C. 18  D. 20

( ) 11. 独根树的高度为 1,具有 61 个结点的完全二叉树的高度为( )。
A. 5  B. 6  C. 7  D. 8

( ) 12. 10000 以内,与 10000 互质的正整数有( )个。
A. 2000  B. 4000  C. 6000  D. 8000

( ) 13. 有以下程序:

#include <iostream>
using namespace std;
int main()
{
    int k = 4, n = 0;
    while (n < k)
    {
        n++;
        if (n % 3 != 0)
            continue;
        k--;
    }
    cout << k << "," << n << endl;
    return 0;
}

程序运行后输出的结果是( )。
A. 2,2  B. 2,3  C. 3,2  D. 3,3

( ) 14. 操作系统的作用是( )。

A. 把源程序译成目标程序  B. 便于进行数据管理
C. 控制和管理系统资源  D. 实现硬件之间的连接

( ) 15. Lucia 和她的朋友以及朋友的朋友都在某社交网站上注册了账号。下图是他 们之间的关系图,两个人之间有边相连代表这两个人是朋友,没有边相连代表不是朋友。这个社交网站的规则是:如果某人 A 向他(她)的朋友 B 分享了某张照片,那么 B 就可以对该照片进行评论;如果 B 评论了该照片,那 么他(她)的所有朋友都可以看见这个评论以及被评论的照片,但是不能对该照片进行评论(除非 A 也向他(她)分享了该照片)。现在 Lucia 已经上传了一张照片,但是她不想让 Jacob 看见这张照片,那么她可以向以下朋友( )分享该照片。 题目图示

A. Dana, Michael, Eve  B. Dana, Eve, Monica
C. Michael, Eve, Jacob  D. Micheal, Peter, Monica


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

(1)

 1  #include <iostream>
 2  #include <cmath>
 3  using namespace std;
 4  
 5  const double r = acos(0.5);
 6  
 7  int a1, b1, c1, d1;
 8  int a2, b2, c2, d2;
 9  
10  inline int sq(const int x) { return x * x; }
11  inline int cu(const int x) { return x * x * x; }
12  
13  int main()
14  {
15      cout.flags(ios::fixed);
16      cout.precision(4);
17  
18      cin >> a1 >> b1 >> c1 >> d1;
19      cin >> a2 >> b2 >> c2 >> d2;
20  
21      int t = sq(a1 - a2) + sq(b1 - b2) + sq(c1 - c2);
22  
23      if (t <= sq(d2 - d1)) cout << cu(min(d1, d2)) * r * 4;
24      else if (t >= sq(d2 + d1)) cout << 0;
25      else {
26          double x = d1 - (sq(d1) - sq(d2) + t) / sqrt(t) / 2;
27          double y = d2 - (sq(d2) - sq(d1) + t) / sqrt(t) / 2;
28          cout << (x * x * (3 * d1 - x) + y * y * (3 * d2 - y)) * r;
29      }
30      cout << endl;
31      return 0;
32  }

假设输入的所有数的绝对值都不超过 1000,完成下面的判断题和单选题:

判断题

( ) 16. (1.5分) 将第 21 行中 t 的类型声明从 int 改为 double,不会影响程序运行的结果。( )

( ) 17. (1.5分) 将第 26、27 行中的“/sqrt(t)/2”替换为“/2 /sqrt(t)”,不会影响程序运行的结果。( )

( ) 18. (1.5分) 将第 28 行中的“x * x”改成“sq(x)”、“y * y”改成“sq(y)”,不会影响程序运行的结果。( )

( ) 19. (1.5分) 当输入为“0 0 0 1 1 0 0 1”时,输出为“1.3090”。( )

单选题

( ) 20. (3分) 当输入为“1 1 1 1 1 1 1 2”时,输出为( )。
A. “3.1416”  B. “6.2832”  C. “4.7124”  D. “4.1888”

( ) 21. (3分) 这段代码的含义为( )
A. 求圆的面积并  B. 求球的体积并  C. 求球的体积交  D. 求椭球的体积并

(2)

 1  #include <iostream>
 2  using namespace std;
 3  
 4  long long n, ans;
 5  int k, len;
 6  long long d[1000000];
 7  
 8  int main() {
 9      cin >> n >> k;
10      d[0] = 0;
11      len= 1;
12      ans = 0;
13      for (long long i = 0; i <n; ++i) {
14          ++d[0];
15          for (int j = 0; j + 1<len; ++j) {
16              if (d[j] == k) {
17                  d[j] = 0;
18                  d[j + 1] += 1;
19                  ++ans;
20              }
21          }
22          if (d[len - 1] == k) {
23              d[len - 1] = 0;
24              d[len] =1;
25              ++len;
26              ++ans;
27          }
28      }
29      cout << ans << endl;
30      return 0;
31  }

假设输入的 n 是不超过 2^{62} 的正整数,k 是不超过 10000 的正整数,完成下面的判断题和单选题。

判断题

( ) 22. (1.5分) 若 $k=1$,则输出 ans 时,len = n。( )

( ) 23. (1.5分) 若 $k>1$,则输出 ans 时,len 一定小于 $n$。( )

( ) 24. (1.5分) 若 $k>1$,则输出 ans 时,k^{\mathrm{len}} 一定大于 $n$。( )

单选题

( ) 25. (3分) 若输入的 $n=10^{15}$,$k=1$,则输出等于( )。
A. $1$  B. $(10^{30}-10^{15})/2$  C. $(10^{30}+10^{15})/2$  D. 10^{15}

( ) 26. (3分) 若输入的 $n=205891132094649$(即 $3^{30}$),$k=3$,则输出等于( )。
A. $3^{30}$  B. $(3^{30}-1)/2$  C. $3^{30}-1$  D. (3^{30}+1)/2

( ) 27. (3分) 若输入的 $n=100010002000090$,$k=10$,则输出等于( )。
A. 11112222444543  B. 11122222444453
C. 11122222444543  D. 11112222444453

(3)

 1  #include <stdio.h>
 2  
 3  #define n 100000
 4  #define	N n+1
 5  
 6  int m;
 7  int a[N], b[N], c[N], d[N];
 8  int f[N], g[N];
 9  
10  void init()
11  {
12      f[1] = g[1] = 1;
13      for (int i = 2; i <= n; i++) {
14          if (!a[i]) {
15              b[m++] = i;
16              c[i] = 1, f[i] = 2;
17              d[i] = 1, g[i] = i + 1;
18          }
19          for (int j = 0; j < m && b[j] * i <= n; j++) {
20              int k = b[j];
21              a[i * k] = 1;
22              if (i % k == 0) {
23                  c[i * k] = c[i] + 1;
24                  f[i * k] = f[i] / c[i * k] * (c[i * k] + 1);
25                  d[i * k] = d[i];
26                  g[i * k] = g[i] * k + d[i];
27                  break;
28              }
29              else {
30                  c[i * k] = 1;
31                  f[i * k] = 2 * f[i];
32                  d[i * k] = g[i];
33                  g[i * k] = g[i] * (k + 1);
34              }
35          }
36      }
37  }
38  
39  int main()
40  {
41      init();
42  
43      int x;
44      scanf("%d", &x);
45      printf("%d %d\n", f[x], g[x]);
46      return 0;
47  }

假设输入的x是不超过1000的自然数,完成下面的判断题和单选题:

判断题

( ) 28. (1.5分) 若输入不为"1",把第12行删去不会影响输出的结果。( )

( ) 29. (2分) 第24行 f[i*k] = f[i] / c[i*k] * (c[i*k] + 1) 中的“$f[i]/c[i*k]$”可能存在无法整除而向下取整的情况。( )

( ) 30. (2分) 在执行完init()后,f数组不是单调递增的,但g数组是单调递增的。( )

单选题

( ) 31. (3分) init函数的时间复杂度为( )。
A. $O(n)$  B. O(nlogn)  C. O(n√n)  D. O(n²)

( ) 32. (3分) 在执行完init()后,f[1], f[2], f[3].....f[100]中有( )个等于2。
A. 23  B. 24  C. 25  D. 26

( ) 33. (4分) 当输入"1000"时,输出为( )。
A. "15 1340"  B. "15 2340"  C. "16 2340"  D. "16 1340"


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

(1)

对于一个1到 n 的排列 P (即1到 n 中每一个数在 P 中出现了恰好一次),令 q[i] 为第 i 个位置之后第一个比 P[i] 值更大的位置,如果不存在这样的位置,则q[i] = n + 1 。举例来说,如果 n = 5 且 P 为15423,则 q 为26656。

下列程序读入了排列 P ,使用双向链表求解了答案。试补全程序。

 1  #include <iostream>
 2  using namespace std;
 3  const int N = 100010;
 4  int n;
 5  int L[N], R[N], a[N];
 6  int main() {
 7      cin >> n;
 8      for (int i = 1; i <= n; ++i) {
 9          int x;
10          cin >> x;
11          __(1)__ ;
12      }
13      for (int i = 1; i <= n; ++i) {
14          R[i] = __(2)__ ;
15          L[i] = i - 1;
16      }
17      for (int i = 1; i <= n; ++i) {
18          L[__(3)__] = L[a[i]];
19          R[L[a[i]]] = R[__(4)__];
20      }
21      for (int i = 1; i <= n; ++i) {
22          cout << __(5)__ << " ";
23      }
24      cout << endl;
25      return 0;
26  }

( ) 34. (3分) (1)处应填:________________

( ) 35. (2分) (2)处应填:________________

( ) 36. (3分) (3)处应填:________________

( ) 37. (3分) (4)处应填:________________

( ) 38. (3分) (5)处应填:________________

(2)

2(烧作业)某课作业布置了N(3sNs10000)个题目,第题对应的得分是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]=l;

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