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. 有以下程序: ```cpp #include 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)** ```cpp 1 #include 2 #include 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)** ```cpp 1 #include 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 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)** ```cpp 1 #include 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$ ,使用双向链表求解了答案。试补全程序。 ```cpp 1 #include 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,请依次升序输出。 ```cpp 1 #include 2 #include 3 #define min(a,b)(a=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;`