2021CSP-J5
一、单项选择题(共15题,每题2分,共计30分;每题有且仅有一个正确选项)
1.在8位二进制补码中国,10110110表示的是十进制下的( )
A. 202 B. 74 C. -202 D. -74
2.2020年10月4日是星期日,1984年10月4日是( )
A. 星期日 B. 星期六 C. 星期五 D. 星期四
3.图G是一棵n节点的树,G上有( )条边
A. n B. 2*n C. n-1 D. n+1
4.由五个不同节点构成的树有( )
A. 3125 B. 125 C. 32 D. 1024
5.有一个长为6的A序列:{3,20,4,6,1},现通过进行交换其中相邻两个数字的操作进行排序,要将A序列排成从小到大的递增序列最少要进行多少次交换操作( )
A. 5 B. 6 C. 7 D. 15
6.某算法计算时间表示为递推关系式:T(N)=N+T(N/2),则该算法时间复杂度为( )
A. O(n*n) B. O(N log N) C. O(N) D. O(1)
7.一棵6节点二叉树的中序遍历为DBAGECF,先序遍历为ABDCEGF,后序遍历为( )
A. DGBEFAC B. GBEACFD C. DBGEFCA D. ABCDEFG
8.一张有9个节点的无向图最多有( )条边
A. 40 B. 81 C. 72 D. 36
9.下列不属于面向对象程序设计语言的是( )
A. C++ B. C C. JAVA D. C#
10.同时查找2n个数中的最大值和最小值,最少比较次数为( )
A. 3(n-2)/2 B. 3n-2 C. 4n-2 D. 2n-2
11.设A和B是两个长为n的有序数组,现在需要将A和B合并成一个排好序的数组,请问任何以元素比较作为基本运算的归并算法最坏情况下至少要做( )次比较。
A. n^2 B. n log{n} C. 2n D. 2n-1
12.前缀表达式 - + * 4 + 2 3 1 5 的值是( )
A. 15 B. 16 C. 17 D. 19
13.两个指针( )
A.任何时候都不能相减
B.如果同时指向一个变量,则此后就不能再指向其它变量了。
C.可在一定条件下相加。
D.可在一定条件下进行相等或不等的比较运算。
14.由四个不同的点构成的简单无向连通图的个数是( )
A. 32 B. 35 C. 38 D. 31
15.某中学有2名男同学,2名女同学和两名老师要排队参加体检。他们排成一条直线,并且任意两名女同学不能相邻,两名老师也不能相邻,那么一共有多少种排法( )
A.240 B. 336 C. 256 D. 624
二、阅读程序(程序输入不超过数组或字符串定义的范围;判断题正确填 T,错误填F;除特殊说明外,判断题1.5分,选择题4分,共计40分)
1)
1.#include<iostream>
2.using namespace std;
3.int a,b,c;
4.int* cal(int *p,int &q,int r){
5. q+=r;
6. *p+=q;
7. return p;
8.}
9.int main(){
10. cin>>a>>b>>c;
11. c=*cal(&a,b,c);
12. cout<<a<<" "<<b<<" "<<c;
13.}
16.(1分)cal函数中参数p使用指针传递,q和r则是值传递
17.(1分)cal函数返回一个指向int类型存储空间的地址
18.(1分)将第6行代码改为 p+=&q,结果不变。
19.当输入1 2 3时,程序输出结果为( )
A. 6 2 3 B. 6 5 3 C. 6 5 6 D. 1 2 6
20.当输入23 45 11时,程序输出结果为( )
A. 79 56 11 B. 79 56 79 C. 44 56 79 D. 79 56 44
2)
1.#include<iostream>
2.#include<algorithm>
3.#include<cstdio>
4.using namespace std;
5.int w[35000],d[35000],dp[35000];
6.int main(){
7. int n,m;
8. scanf("%d%d",&n,&m);
9. for(int i=1;i<=n;i++)
10. scanf("%d%d",&w[i],&d[i]);
11. for(int i=1;i<=n;i++)
12. for(int j=m;j>=w[i];j--)
13. dp[j]=max(dp[j],dp[j-w[i]]+d[i]);
14. printf("%d\n",dp[m]);
15. return 0;
16.}
21.上述代码中,第12行双重循环里循环变量j的枚举顺序改为w[i] 到m,输出结果一定不变
22.上述代码中,第11行双重循环里循环变量i的枚举顺序改为n到1,输出结果一定不变
23.若输入数据中,1≤n≤30000,1≤m≤30000,1≤w[i]≤30000,1≤d[i]≤30000,则所求答案一定没有溢出
24.若输入数据中,1≤n≤30000,1≤m≤30000,1≤w[i]≤30000,1≤d[i]≤3000000,则所求答案一定没有溢出
25.当输入为:
4 6
1 4
2 6
3 12
2 7
输出为( )
A. 17 B. 28 C. 29 D. 23
26.上述代码的时间复杂度为( )
A.O(n) B. O(n*n*m) C. O(n*m) D. O(n*m*m)
3)
1.#include<iostream>
2.#include<cstring>
3.#include<cstdio>
4.#define N 500+10
5.using namespace std;
6.int a[N],n;
7.int main(){
8. cin>>n;
9. for (int i=1;i<=n;i++) cin>>a[i];
10. for (int i=1;i<n;i++){
11. int tmp=i;
12. for (int j=i+1;j<=n;j++)
13. if (a[j]<a[tmp]) tmp=j;
14. swap(a[i],a[tmp]);
15. }
16. for (int i=1;i<=n;i++) cout<<a[i]<<" ";
17. cout<<endl;
18. return 0;
19.}
27.上述代码实现了对一个长度为n的序列进行排序
28.若将13、14行语句合并修改为
1.if (a[j]<a[i]) swap(a[i],a[j]);
则算法的时间复杂度将增大
29.(1分)去掉头文件 #include<cstdio> 后程序仍能正常编译运行
30.(1分)去掉 using namespace std; 后程序仍能正常编译运行
31.(2分)我们将上述算法称为( )
A. KMP B. 冒泡排序 C. 选择排序 D. 归并排序
32.上述代码的时间复杂度为( )
A. O(n) B. O(n log n) C. O(n*n) D. O(n*n*n)
33.若输入数据为:
5
3 2 1 5 4
则if(a[j]<a[tmp]) 这句话中的条件会成立多少次
A. 5 B. 7 C. 3 D. 4
三、完善程序(每小题3分,共计30分)
1)请完善下面的程序,使用BFS统计一张边权都为1的图中,从给定起点到所有点的距离:
1.#include<algorithm>
2.#include<cstdio>
3.#include<vector>
4.#define N 200020
5.using namespace std;
6.int n,m;
7.vector<int>G[N];
8.int q[N],hd,tl;
9.int dis[N];
10.void BFS( ① ){
11. hd=1,tl=0;
12. for (int i=1;i<=n;i++) dis[i]=-1;
13. q[++tl]=st,dis[st]=0;
14. while( ② ){
15. int u=q[hd++];
16. for (int i=0;i<G[u].size();i++){
17. int v=G[u][i];
18. if ( ③ ) continue;
19. dis[v]=dis[u]+1;
20. q[++tl]=v;
21. }
22. }
23.}
24.int main(){
25. scanf("%d%d",&n,&m);
26. for (int i=1;i<=n;i++){
27. int x,y;
28. scanf("%d%d",&x,&y);
29. G[x].push_back(y);
30. ④
31. }
32. int st;
33. scanf("%d",&st);
34. BFS(st);
35. for( ⑤ )
36. printf("%d",dis[i]);
37.}
34.①处应填( )
A. int u; B. int st; C. int &st; D. int st
35.②处应填( )
A. ht<tl B. hd>tl C. hd<=tl D. hd>=tl
36.③处应填( )
A. vis[v]==true B. dis[v]<=dis[u] C. dis[v]!=-1 D. dis[v]>dis[u]
37.④处应填( )
A. G[y].push_back(x) B. G[y].insert(x) C. G[y][x]=1 D. G[y].push(x)
38.⑤处应填( )
A. int j=1;j<=n;j++ B. int i=1;i<=n;i++ C. int i=0;i<n;i++ D. int i=1,i<=n,i++
2)
(链表反转)单向链表反转是一道经典算法问题,比如有一个链表是这样的,1->2->3->4->5,反转后成为5->4->3->2->1。现给定如下链表节点的定义:
1.struct LinkNode{
2. int value;
3. LinkNode* next;
4.};
非递归实现:
1.LinkNode* Reverse(LinkNode* header){
2. if (header==NULL||header->next==NULL){
3. return header;
4. }
5. LinkNode* pre=header,*cur=header->next;
6. pre->next=NULL;
7. while(cur!=NULL){
8. LinkNode* next= ① ;
9. ② =pre;
10. pre=cur;
11. cur=next;
12. }
13. return pre;
14.}
递归实现:
1.LinkNode* Reverse(LinkNode* head){
2. if (head==NULL||head->next==NULL){
3. return head;
4. }
5. LinkNode* newhead= ③ ;
6. ④ =head;
7. head->next= ⑤ ;
8. return newhead;
9.}
39.①处应填( )
A. pre->next B. cur->next; C. header->next D. NULL
40.②处应填( )
A. pre->next B. cur->next; C. header->next D. NULL
41.③处应填( )
A.Reverse(head)
B.Reverse(pre)
C.Reverse(cur)
D.Reverse(head->next)
42.④处应填( )
A.newhead->next
B.head->next
C.head->next->next
D.newhead->next->next
43.⑤处应填( )
A.newhead->next
B.head
C.newhead
D.NULL
别找我要答案,国庆假期结束后的5天,只要有时间,我就会发^_^