CSP 2019 入門組第一輪試題
CSP 2019 入門組第一輪
一、單選(共15題,每題2分,共計30分)
第 1 題
中國的國家頂級域名是()
A. .cn
B. .ch
C. .chn
D. .china
第 2 題
二進位制數11 1011 1001 0111和01 0110 1110 1011進行邏輯與運算的結果是()。
A. 01 0010 1000 1011
B. 01 0010 1001 0011
C. 01 0010 1000 0001
D. 01 0010 1000 0011
第 3 題
一個32位整型變數佔用()個位元組。
A. 32
B. 128
C. 4
D. 8
第 4 題
若有如下程式段,其中s、a、b、c均已定義為整型變數,
且a、c均已賦值(c大於0)
s=a;
for(b=1; b<=c; b++) s=s-1;
則與上述程式段功能等價的賦值語句是()
A. s = a - c;
B. s = a - b;
C. s = s - c;
D. s = b - c;
第 5 題
設有100個已排好序的資料元素,採用折半查詢時,最大比較次數為()
A. 7
B. 10
C. 6
D. 8
解析:2^k>=100, k>=7
第 6 題
連結串列不具有的特點是()
A. 插入刪除不需要移動元素 B. 不必事先估計儲存空間 C. 所需空間與線性表長度成正比 D. 可隨機訪問任一元素
第 7 題
把8個同樣的球放在5個同樣的袋子裡,允許有的袋子空著不放,問共有多少種不同的分法?()
提示:如果8個球都放在一個袋子裡,無論是哪個袋子,都只算同一種分法。
A. 22
B. 24
C. 18
D. 20
解析:
當放入1個袋子時:1 8=8 當放入2個袋子時:4 1+7=8 2+6=8 3+5=8 4+4=8 當放入3個袋子時:5 1+1+6=8 1+2+5=8 1+3+4=8 2+2+4=8 2+3+3=8 當放入4個袋子時:5 1+1+1+5=8 1+1+2+4=8 1+1+3+3=8 1+2+2+3=8 2+2+2+2=8 當放入5個袋子時:3 1+1+1+1+4=8 1+1+1+2+3=8 1+1+2+2+2=8 共: 1+4+5+5+3=18
第 8 題
一棵二叉樹如右圖所示,若採用順序儲存結構,即用一維陣列元素儲存該二叉樹中的結點(根結點的下標為1,若某結點的下標為i ,則其左孩子位於下標2i處、右孩子位於下標2i+l處),則該陣列的最大下標至少為()。
A. 6
B. 10
C. 15
D. 12
第 9 題
100以內最大的素數是()。
A. 89
B. 97
C. 91
D. 93
第 10 題
319和377的最大公約數是()。
A. 27
B. 33
C. 29
D. 31
第 11 題
新學期開學了,小胖想減肥,健身教練給小胖制定了兩個訓練方案。
方案一:每次連續跑3公里可以消耗300千卡(耗時半小時);
方案二:每次連續跑5公里可以消耗600千卡(耗時1小時)。
小胖每週週一到週四能抽出半小時跑步,週五到週日能抽出一小時跑步。
另外,教練建議小胖每週最多跑21公里,否則會損傷膝蓋。
請問如果小胖想嚴格執行教練的訓練方案,並且不想損傷膝蓋,每週最多通過跑步消耗多少千卡?()
A. 3000
B. 2500
C. 2400
D. 2520
第 12 題
—副紙牌除掉大小王有52張牌,四種花色,每種花色13張。
假設從這52張牌中隨機抽取13張紙牌,則至少()張牌的花色一致。
A. 4
B. 2
C. 3
D. 5
第 13 題
—些數字可以顛倒過來看,例如0、1、8顛倒過來還是本身,6顛倒過來是9, 9顛倒過來看還是6,其他數字顛倒過來都不構成數字。
類似的,一些多位數也可以顛倒過來看,比如106顛倒過來是901。假設某個城市的車牌只由5位數字組成,每一位都可以取0到9。
請問這個城市最多有多少個車牌倒過來恰好還是原來的車牌?()
A. 60
B. 125
C. 75
D. 100
第 14 題
假設一棵二叉樹的後序遍歷序列為DGJHEBIFCA,中序遍歷序列為DBGEHJACIF,則其前序遍歷序列為()。
A. ABCDEFGHIJ
B. ABDEGHJCFI
C. ABDEGJHCFI
D. ABDEGHJFIC
第 15 題
以下哪個獎項是電腦科學領域的最高獎?()
A. 圖靈獎
B. 魯班獎
C. 諾貝爾獎
D. 普利策獎
二、閱讀程式(除特殊說明外,判斷題1.5分,選擇題3分,共計40分)
程式輸入不超過陣列或字串定義的範圍;
判斷題正確填√,錯誤填×;
第 16 題(本題共 12 分)
#include <cstdio>
#include <cstring>
using namespace std;
char st[100];
int main() {
scanf("%s", st);
int n = strlen(st);
for (int i = 1; i <= n; ++i) {
if (n % i == 0) {
char c = st[i - 1];
if (c >= 'a')
st[i - 1] = c - 'a' + 'A';
}
}
printf("%s", st);
return 0;
}
判斷題
- 輸入的字串只能由小寫字母或大寫字母組成。()
- 若將第8行的“i = 1”改為“i = 0”,程式執行時會發生錯誤。()
- 若將第8行的“i <= n”改為“i * i <= n”,程式執行結果不會改變。()
- 若輸入的字串全部由大寫字母組成,那麼輸出的字串就跟輸入的字串一樣。()
選擇題
- 若輸入的字串長度為18,那麼輸入的字串跟輸出的字串相比,至多有()個字元不同。
A. 18
B. 6
C. 10
D. 1
- 若輸入的字串長度為(),那麼輸入的字串跟輸出的字串相比,至多有36個字元不同。
A. 36
B. 100000
C. 1
D. 128
第 17 題(本題共 12 分)
#include<cstdio>
using namespace std;
int n, m;
int a[100], b[100];
int main() {
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; ++i)
a[i] = b[i] = 0;
for (int i = 1; i <= m; ++i) {
int x, y;
scanf("%d%d", &x, &y);
if (a[x] < y && b[y] < x) {
if (a[x] > 0)
b[a[x]] = 0;
if (b[y] > 0)
a[b[y]] = 0;
a[x] = y;
b[y] = x;
}
}
int ans = 0;
for (int i = 1; i <= n; ++i) {
if (a[i] == 0)
++ans;
if (b[i] == 0)
++ans;
}
printf("%d", ans);
return 0;
}
假設輸入的n和m都是正整數,x和y都是在[1, n]的範圍內的整數,完成下面的判斷題和單選題:
判斷題
- 當m>0時,輸出的值一定小於2n。()
- 執行完第27行的"++ans"時,ans —定是偶數。()
- a[i]和b[i]不可能同時大於0。()
- 右程式執行到第13行時,x總是小於y,那麼第15行不會被執行。()
選擇題
- 若m個x兩兩不同,且m個y兩兩不同,則輸出的值為()
A. 2n-2m
B. 2n+2
C. 2n-2
D. 2n
- 若m個x兩兩不同,且m個y都相等,則輸出的值為()
A. 2n-2
B. 2n
C. 2m
D. 2n-2m
第 18 題(本題共 16 分)
#include <iostream>
using namespace std;
const int maxn = 10000;
int n;
int a[maxn];
int b[maxn];
int f(int l, int r, int depth) {
if (l > r)
return 0;
int min = maxn, mink;
for (int i = l; i <= r; ++i) {
if (min > a[i]) {
min = a[i];
mink = i;
}
}
int lres = f(l, mink - 1, depth + 1);
int rres = f(mink + 1, r, depth + 1);
return lres + rres + depth * b[mink];
}
int main() {
cin >> n;
for (int i = 0; i < n; ++i)
cin >> a[i];
for (int i = 0; i < n; ++i)
cin >> b[i];
cout << f(0, n - 1, 1) << endl;
return 0;
}
判斷題
- 如果a陣列有重複的數字,則程式執行時會發生錯誤。()
- 如果b陣列全為0,則輸出為0。()
選擇題
- 當n=100時,最壞情況下,與第12行的比較運算執行的次數最接近的是:()。
A. 5000
B. 600
C. 6
D. 100
- 當n=100時,最好情況下,與第12行的比較運算執行的次數最接近的是:()。
A. 100
B. 6
C. 5000
D. 600
- 當n=10時,若b陣列滿足,對任意0<=i<n,都有b[i] = i + 1,那麼輸出最大為()。
A. 386
B. 383
C. 384
D. 385
- 當n=100時,若b陣列滿足,對任意0 S i < 71,都有b[i]=1,那麼輸出最小為()。
A. 582
B. 580
C. 579
D. 581
三、完善程式(單選題,每小題 3 分,共計 30 分)
第 19 題(本題共 15 分)
1.(矩陣變幻)有一個奇幻的矩陣,在不停的變幻,其變幻方式為:
數字 0 變成矩陣
0 0
0 1
數字 1 變成矩陣
1 1
1 0
最初該矩陣只有一個元素 0,變幻 n 次後,矩陣會變成什麼樣?
例如,矩陣最初為:[0];
矩陣變幻 1 次後:
0 0
0 1
矩陣變幻 2 次後:
0 0 0 0
0 1 0 1
0 0 1 1
0 1 1 0
輸入一行一個不超過 10 的正整數 n。輸出變幻 n 次後的矩陣。試補全程式。
提示:<< 表示二進位制左移運算子,例如(11)2 << 2 = (1100)2
而 ^ 表示二進位制異或運算子,它將兩個參與運算的數中的每個對應的二進位制位—進行比較,若兩個二進位制位相同,則運算結果的對應二進位制位為 0 ,反之為 1。
#include <cstdio>
using namespace std;
int n;
const int max_size = 1 << 10;
int res[max_size][max_size];
void recursive(int x, int y, int n, int t) {
if (n == 0) {
res[x][y] = ①;
return;
}
int step = 1 << (n - 1);
recursive(②, n - 1, t);
recursive(x, y + step, n - 1, t);
recursive(x + step, y, n - 1, t);
recursive(③, n - 1, !t);
}
int main() {
scanf("%d", &n);
recursive(0, 0, ④);
int size = ⑤;
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++)
printf("%d", res[i][j]);
puts("");
}
return 0;
}
①處應填()
②處應填()
③處應填()
④處應填()
⑤處應填()
-
A. n%2 B. 0 C. t D. 1
-
A. x-step,y-step B. x,y-step C. x-step,y D. x,y
-
A. x-step,y-step B. x+step,y+step C. x-step,y D. x,y-step
-
A. n-1,n%2 B. n,0 C. n,n%2 D. n-1,0
-
A. 1<<(n+1) B. 1<<n C. n+1 D. 1<<(n-1)
第 20 題(本題共 15 分)
2.(計數排序)計數排序是一個廣泛使用的排序方法。下面的程式使用雙關鍵字計數排序,將n對10000以內的整數,從小到大排序。
例如有三對整數(3,4)(3,4)、(2,4)(2,4)、(3,3)(3,3),那麼排序之後應該是(2,4)(2,4)、(3,3)(3,3)、(3,4)(3,4) 。
輸入第一行為nn,接下來nn行,第ii行有兩個數 a[i]和 b[i],分別表示第ii對整數的第一關鍵字和第二關鍵字。
從小到大排序後輸出。
資料範圍 1<n<10^7, 1<a[i],b[i]<10^4
提示:應先對第二關鍵字排序,再對第一關鍵字排序。陣列ord[]儲存第二關鍵字排序的結果,陣列res[]儲存雙關鍵字排序的結果。
試補全程式。
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 10000000;
const int maxs = 10000;
int n;
unsigned a[maxn], b[maxn],res[maxn], ord[maxn];
unsigned cnt[maxs + 1];
int main() {
scanf("%d", &n);
for (int i = 0; i < n; ++i)
scanf("%d%d", &a[i], &b[i]);
memset(cnt, 0, sizeof(cnt));
for (int i = 0; i < maxs; ++i)
①; // 利用 cnt 陣列統計數量
for (int i = 0; i < n; ++i)
cnt[i + 1] += cnt[i];
for (int i = 0; i < n; ++i)
②; // 記錄初步排序結果
memset(cnt, 0, sizeof(cnt));
for (int i = 0; i < n; ++i)
③; // 利用 cnt 陣列統計數量
for (int i = 0; i < maxs; ++i)
cnt[i + 1] += cnt[i];
for (int i = n - 1; i >= 0; --i)
④ // 記錄最終排序結果
for (int i = 0; i < n; i++)
printf("%d %d", ⑤);
return 0;
}
①處應填()
②處應填()
③處應填()
④處應填()
⑤處應填()
-
A. ++cnt [i] B. ++cnt[b[i]] C. ++cnt[a[i] * maxs + b[i]] D. ++cnt[a[i]]
-
A. ord[--cnt[a[i]]] = i B. ord[--cnt[b[i]]] = a[i] C. ord[--cnt[a[i]]] = b[i] D. ord[--cnt[b[i]]] = i
-
A. ++cnt[b[i]] B. ++cnt[a[i] * maxs + b[i]] C. ++cnt[a[i]] D. ++cnt [i]
-
A. res[--cnt[a[ord[i]]]] = ord[i] B. res[--cnt[b[ord[i]]]] = ord[i] C. res[--cnt[b[i]]] = ord[i] D. res[--cnt[a[i]]] = ord[i]
-
A. a[i], b[i] B. a[res[i]], b[res[i]] C. a[ord[res[i]]]j b[ord[res[i]]] D. a[res[ord[i]]]j b[res[ord[i]]]