2021 CCF 非專業級別軟件能力認證第一輪
(CSP-J1) 入門級 C 語言試題
認證時間: 2021年9月19日 14:30 ~16:30
1.以下不屬於面向對象程序設計語言是
A. C++
B. Python
C. Java
D. C
2.以下獎項與計算機領域相關的是
A. 奧斯卡獎
B. 圖靈獎
C. 諾貝爾獎
D. 普利策獎
3.目前主流的計算機存儲數據最終都是轉換成( ) 數據進行存儲的
A. 二進制
B. 十進制
C. 八進制
D. 十六進制
4.以比較作為基本運算,在N個數中找出最大數,最壞情況下所需要的最少比較次數為
A. $N^2$
B. N
C. N-1
D. N+1
5.對於入棧順序為a,b,c,d,e的序列,下列( )不合法的出棧序列
A. a,b,c,d,e
B. e,d,c,b,a
C. b,a,c,d,e
D. c,d,a,e,b
6.對於有n個頂點、m條邊的無向連通圖(m>n),需要刪掉( )條邊才能使其成為一棵樹
A. n-1
B. m-n
C. m-n-1
D. m-n+1
7.二進制數101.11對應的十進制數是( )
A. 6.5
B. 5.5
C. 5.75
D. 5.25
8.如果一顆二叉樹只有根節點,那么這棵二叉樹高度為1。請問高度為5的完全二叉樹有( )種不同的形態
A. 16
B. 15
C. 17
D. 32
9.表達式a* (b+c)* d的后綴表達式為( ),其中 *和 +是運算符
A. * * a + b c d
B. a b c + * d *
C. a b c + d * *
D. * a * + b c d
10.6個人,兩個人組一對,總共組成三隊,不區分隊伍的編號。不同的組隊情況有( )
A. 10
B. 15
C. 30
D. 20
11.在數據壓縮編碼中的哈夫曼編碼方法,在本質上是一種( ) 策略
A. 枚舉
B. 貪心
C. 遞歸
D. 動態規划
12.由 1,1,2,2,3這五個數字組成不同的三位數有( )種
A. 18
B. 15
C. 12
D. 24
13.考慮如下遞歸算法
solve()
if n<=1 return 1
else if n>=5 return n*solve(n-2)
else return n*solve(n-1)
則調用solve(7)得到的返回結果為( )
A. 105
B. 840
C. 210
D. 420
14.以a為起點,對右邊的無向圖進行深度優先遍歷,則b、c、d、e四個點中有可能作為最后一個遍歷的點的個數為( )
A. 1
B. 2
C. 3
D. 4
15.有四個人要從A點坐一條船過河到B點,船一開始在A點。該船一次最多可坐兩個人。已知這四個人中每個人獨自坐船的過河時間分別為1、2、4、8,且兩個人坐船的過河時間為兩人獨自過河時間的較大者。則最短( )時間可以讓四個人都過河到B點(包括從B點把船開回A點的時間)
A. 14
B. 15
C. 16
D. 17
二 閱讀程序(判斷題1.5分 選擇題3分 共計40分 )
#include<stdio.h>
int n;
int a[1000];
int f(int x)
{
int ret = 0;
for(;x;x&=x-1) ret++;
return ret;
}
int g(int x)
{
return x & -x;
}
int main()
{
scanf("%d",&n);
for (int i=0;i<n;i++) scanf("%d",&a[i]);
for(int i=0;i<n;i++)
printf("%d ",f(a[i])+g(a[i]));
printf("\n");
return 0;
}
判斷題
16.輸入的n等於1001時,程序不會發生下標越界( )
17.輸入的a[i]必須全為正整數,否則程序將陷入死循環( )
18.當輸入為“5 2 11 9 16 10” 時,輸出“3 4 3 17 5” ( )
19.當輸入為“1 511998 ”時,輸出為"18" ( )
20.將原碼中g函數的定義(13 -16行) 移到main函數的后面,程序可以正常編譯運行( )
單選題
21.當輸入為"2 -65536 2147483647"時,輸出為 ( )
A. "65532 33"
B. "65532 32"
C. "65535 34"
D. "65554 33"
#include<stdio.h>
#include<string.h>
char base[64];
char table[256];
char str[256];
char ans[256];
void init()
{
for(int i=0;i<26;i++) base[i]='A'+i;
for(int i=0;i<26;i++) base[26+i]='a'+i;
for(int i=0;i<10;i++) base[52+i]='0'+i;
base[62]='+',base[63]='/';
for(int i=0;i<256;i++) table[i]=0xff;
for(int i=0;i<64;i++) table[base[i]]=i;
table['=']=0;
}
void decode(char *str)
{
char *ret = ans;
int i,len = strlen(str);
for(i=0;i<len;i+=4){
(*ret++) =table[str[i]]<<2|table[str[i+1]]>>4;
if(str[i+2]!='=')
(*ret++)=(table[str[i+1]]&0x0f)<<4|table[str[i+2]]>>2;
if(str[i+3]!='=')
(*ret++)=table[str[i+2]]<<6|table[str[i+3]];
}
}
int main()
{
init();
printf("%d\n",(int)table[0]);
scanf("%s",str);
decode(str);
printf("%s\n",ans);
return 0;
}
判斷題
22.輸出的第二行一定是由小寫字母、大寫字母、數字和"+"、"/"、"="構成的字符串( )
23.可能存在輸入不同,但輸出的第二行相同的情形( )
24.輸出的第一行為"-1" ( )
單選題
25.設輸入字符串長度為n,decode函數的時間復雜度為( )
A. O($\sqrt{n}$)
B. O(n)
C. O(n log n)
D. O($n^2$)
26.當輸入為"Y3NX"時,輸出的第二行為( )
A. "csp"
B. "csq"
C. "CSP"
D. "Csp"
27.(3.5分)當輸入為"Y2NmIDIwMjE"時,輸出的第二行為( )
A. "ccf2021"
B. "ccf2022"
C. "ccf 2021"
D. "ccf 2022"
#include<stdio.h>
#define n 100000
#define N n+1
int m;
int a[N],b[N],c[N],d[N];
int f[N],g[N];
void init()
{
f[1]=g[1]=1;
for(int i=2;i<=n;i++){
if(!a[i]){
b[m++]=i;
c[i]=1,f[i]=2;
d[i]=1,g[i]=i+1;
}
for(int j=0;j<m&&b[j]*i<=n;j++){
int k=b[j];
a[i*k]=1;
if(i%k==0){
c[i*k]=c[i]+1;
f[i*k]=f[i]/c[i*k]*(c[i*k]+1);
d[i*k]=d[i];
g[i*k]=g[i]*k+d[i];
break;
}
else{
c[i*k]=1;
f[i*k]=2*f[i];
d[i*k]=g[i];
g[i*k]=g[i]*(k+1);
}
}
}
}
int main()
{
init();
int x;
scanf("%d",&x);
printf("%d %d\n",f[x],g[x]);
return 0;
}
假設輸入的x是不超過1000的自然數,完成下面的判斷題和單選題
判斷題
28.若輸入不為"1",把第12刪去不會影響輸出的結果( )
29.(2分) 第24行的"f[i]/c[i*k]"可能存在的無法整除而向下取取整的情況( )
30.(2分)在執行完init()后,f數組不是單調遞增的,但g數組是單調遞增的( )
單選題
31.init 函數的時間復雜度為( )
A. O(n)
B. O(nlogn)
C. O(n $\sqrt{n}$)
D. O($n^2$)
32.在執行完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"
三、 完善程序 (單選題 ,每小題3分,共30分)
1(Josephus問題)有n個人圍成一個圈,依次標號0至n-1。從0號開始,依次 0,1,0,1...交替報數,報到1的人會離開,直至只剩下一個人。求最后剩下人的編號
試補全模擬程序
#include<stdio.h>
const int MAXN=1000000;
int F[MAXN];
int main(){
int n;
scanf("%d",&n);
int i=0,p=0,c=0;
while(①){
if(F[i]==0){
if(②){
f[i]=1;
③;
}
④
}
⑤;
}
int ans=-1;
for(i=0;i<n;i++)
if(F[i]==0)
ans=i;
printf("%d\n",ans);
return 0;
}
34.①處應填( )
A. i<n
B. c<n
C. i<n-1
D. c<n-1
35.②處應該填( )
A. i%2==0
B. i%2==1
C. p
D. !p
36.③處應該填( )
A. i++
B. i=(i+1)%n
C. c++
D. p^=1
37.④處應該填( )
A. i++
B. i=(i+1)%n
C. c++
D. p^=1
38.⑤處應該填( )
A. i++
B. i=(i+1)%n
C. c++
D. p^=1
2.(矩形計數)平面上有n個關鍵點,求有多少個四條邊都和x軸或者y軸平行的矩形,滿足四個頂點都是關鍵點。給出的關鍵點可能有重復,但完全重合的矩形只計一次。
試補全枚舉算法
#include<stdio.h>
struct point{
int x,y,id;
};
int equals(struct point a,struct point b){
return a.x==b.x && a.y==b.y;
}
int cmp(struct point a,struct point b){
return ①;
}
void sort(struct point A[],int n){
for(int i=0;i<n;i++)
for(int j=1;j<n;j++)
if(cmp(A[j,a[j-1]])){
struct point t=A[j];
A[j]=A[j-1];
A[j-1]=t;
}
}
int unique(struct point A[],int n){
int t=0;
for(int i=0;i<n;i++)
if(②)
A[t++]=A[i];
return 0;
}
int binary_search(struct point A[],int n,int x,int y){
struct point p;
p.x=x;
p.y=y;
p.id=n;
int a=0,b=n-1;
while(a<b){
int mid=③;
if(④)
a-mid+1;
else
b=mid;
}
return equals(A[a],p);
}
#define MAXN 1000
struct point A[MAXN];
int main(){
int n;
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d %d",&A[i].x,&A[i].y);
A[i].id=i;
}
sort(A,n);
n=unique(A,n);
int ans = 0;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
if( && binary_search(A,n,A[i].x,A[j].y) && binary_search(A,n,A[j].x,A[i].y)){
ans++;
}
printf("%d\n",ans);
return 0;
}
39.①處應填( )
A. a.x!=b.x?a.x<b.x:a.id<b.id
B. a.x!=b.x?a.x<b.x:a.y<b.y
C. equals(a,b)?a.id<b.id:a.x<b.x
D. equals(a,b)?aid<b.id:(a.x!=b.x?a.x<b.x:a.y<b.y)
40.②處應該填( )
A. i==0||cmp(A[i],A[i-1])
B. t==0||equals(A[i],A[t-1])
C. i==0||!cmp(A[i],A[i-1])
D. t==0||!equals(A[i],A[t-1])
41.③處應該填( )
A. b-(b-a)/2+1
B. (a+b+1)>>1
C. (a+b)>>1
D. a+(b-a+1)/2
42.④處應該填( )
A. !cmp(A[mid],p)
B. cmp(A[mid],p)
C. cmp(p,A[mid])
D. !cmp(p,A[mid])
43.⑤處應該填( )
A. A[i].x==a[j].x
B. a[i].id<A[j].id
C. A[i].x==A[j].x && A[i].id<A[j].id
D. A[i].x<A[j]. && A[i].<A[j].y