1. 程式人生 > 其它 >CSP 2019 入門組第一輪試題

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;
}

判斷題

  1. 輸入的字串只能由小寫字母或大寫字母組成。()
  2. 若將第8行的“i = 1”改為“i = 0”,程式執行時會發生錯誤。()
  3. 若將第8行的“i <= n”改為“i * i <= n”,程式執行結果不會改變。()
  4. 若輸入的字串全部由大寫字母組成,那麼輸出的字串就跟輸入的字串一樣。()

選擇題

  1. 若輸入的字串長度為18,那麼輸入的字串跟輸出的字串相比,至多有()個字元不同。
 A. 18
 B. 6
 C. 10
 D. 1
  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]的範圍內的整數,完成下面的判斷題和單選題:

判斷題

  1. 當m>0時,輸出的值一定小於2n。()
  2. 執行完第27行的"++ans"時,ans —定是偶數。()
  3. a[i]和b[i]不可能同時大於0。()
  4. 右程式執行到第13行時,x總是小於y,那麼第15行不會被執行。()

選擇題

  1. 若m個x兩兩不同,且m個y兩兩不同,則輸出的值為()
 A. 2n-2m
 B. 2n+2
 C. 2n-2
 D. 2n
  1. 若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;
}

判斷題

  1. 如果a陣列有重複的數字,則程式執行時會發生錯誤。()
  2. 如果b陣列全為0,則輸出為0。()

選擇題

  1. 當n=100時,最壞情況下,與第12行的比較運算執行的次數最接近的是:()。
 A. 5000
 B. 600
 C. 6
 D. 100
  1. 當n=100時,最好情況下,與第12行的比較運算執行的次數最接近的是:()。
 A. 100
 B. 6
 C. 5000
 D. 600
  1. 當n=10時,若b陣列滿足,對任意0<=i<n,都有b[i] = i + 1,那麼輸出最大為()。
 A. 386
 B. 383
 C. 384
 D. 385
  1. 當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;
}

①處應填()

②處應填()

③處應填()

④處應填()

⑤處應填()

  1.  A. n%2
     B. 0
     C. t
     D. 1
    
  2.  A. x-step,y-step
     B. x,y-step
     C. x-step,y
     D. x,y
    
  3.  A. x-step,y-step
     B. x+step,y+step
     C. x-step,y
     D. x,y-step
    
  4.  A. n-1,n%2
     B. n,0
     C. n,n%2
     D. n-1,0
    
  5.  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;
}

①處應填()

②處應填()

③處應填()

④處應填()

⑤處應填()

  1.  A. ++cnt [i]
     B. ++cnt[b[i]]
     C. ++cnt[a[i] * maxs + b[i]]
     D. ++cnt[a[i]]
    
  2.  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
    
  3.  A. ++cnt[b[i]]
     B. ++cnt[a[i] * maxs + b[i]]
     C. ++cnt[a[i]]
     D. ++cnt [i]
    
  4.  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]
    
  5. 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]]]