1. 程式人生 > >NOIP 2018普及組初賽C/C++答案詳解

NOIP 2018普及組初賽C/C++答案詳解

一、單項選擇題

1 D
印表機是把電腦裡的資料列印到紙上,所以是輸出裝置。
掃描器、鍵盤和滑鼠都是往電腦裡輸入東西,是輸入裝置。

2 D
二進位制化八進位制:從低位(右)往高位(左),每三位直接換成八進位制即可。
(1001101011)2 = (10 0110 1011)2 = (26B)16
二進位制化十六進位制:從低位(右)往高位(左),每四位直接換成十六進位制即可。
(1001101011)2 = (1 001 101 011)2 = (1153)8
這裡可以看出,D答案和A、C答案都不相同,答案必然就是D。

可以進一步將八進位制轉化成十進位制和十六進位制。
十進位制:(1151)8 = (1 * 83 + 1 * 82 + 5 * 8 + 1)10

= (512 + 64 + 40 + 1)10 = (617)10
十六進位制:(1151)8 = (1 001 101 001)2 = (10 0110 1001)2 = (269)16

3 D
1 Byte = 8 bit
1 KB = 1024 B
1 MB = 1024 KB = 1024 * 1024 B
1 GB = 1024 MB = 1024 * 1024 * 1024 B

4 B
LAN: Local Area Network,區域網
WAN: Wide Area Network,廣域網
MAN: 非計算機行業專有名詞
LNA: 非計算機行業專有名詞

5 B
1984年鄧小平指出:“計算機的普及要從娃娃做起。”教育部和中國科協委託中國計算機學會舉辦了全國青少年計算機程式設計競賽(簡稱:NOI),1984年參加競賽的有8000多人。這一新的活動形式受到黨和政府的關懷,得到社會各界的關注與支援。

6 A
跟週期有關。輸出順序為
ASDFasdfASDFasdf……
週期為8,所以第81個字元與第1個字元一樣。

7 A
(1)相關概念
① 二叉樹:樹中每個節點至多有兩個子節點
② 二叉搜尋樹:對於樹中任何節點,如果其左子節點不為空,那麼該節點的value值永遠 >= 其左子節點;如果其右子節點不為空,那麼該節點的value值永遠 <= 其右子節點
③ 滿二叉樹(完美二叉樹):樹中除了葉子節點,每個節點都有兩個子節點
④ 完全二叉樹:最後一層的葉子節點均需在最左邊(上層的結點沒有排滿不能排下層的,左邊的結點沒排滿不能排右邊的)

7.jpg

(2)根結點的深度
通常算做0或是1,具體是0還是1無所謂,保證程式上下文統一即可。
題目中明確指出了根結點是0,所以上面左圖中的深度是3,不是4。
(3)舉特例
k = 2時,即滿二叉樹。
上面左圖中,h = 3, 結點總數為15 = (23+1

- 1) / (2 - 1),A答案對,其他答案都錯。

8 A
氣泡排序要兩兩比較關鍵字。
堆排序每一次交換後都要重新比較關鍵字,形成新的大頂堆。
插入排序也要比較後才知道插入的位置。
與其他排序方法不一樣的是,基數排序不涉及數的比較和交換,只是純粹的排序而已。

冒泡、堆、插入排序可參考《大話資料結構》第9章。
基數排序可參考 https://www.jianshu.com/p/7c9d8a1b7f5d

9 A
(1)思路:
同時取出最大最小值,可以將元素按對來處理,先比較每一對的大小,再把大的和最大值比較,小的和最小值比較。
分奇偶:
奇數個:把最大和最小值都先設為第一個值。
偶數個:把最大和最小分別設為前兩個數。
實際上就是要保證剩下來比較的是偶數個。

(2)程式碼:

public void getMax_Min(int a[])
{
        int len=a.length;
        int max=0,min=0;
        int i=0,j=len-1;
        if(len%2==0)
        {
            if(a[0]>a[1])   //比較
            {   max=a[0];
                min=a[1];
            }
            else
            {
                max=a[1];
                min=a[0];
            }
            i=2;//索引從2開始
        }
        else
        {
            max=a[0];
            min=a[0];
            i=1;//索引從1開始
        }

        while(i<j)
        {
            if(a[i]<a[j])   //比較
            {
                max=a[j]>max?a[j]:max;  //比較
                min=a[i]<min?a[i]:min;  //比較
            }
            else
            {
                max=a[i]>max?a[i]:max;  //比較
                min=a[j]<min?a[j]:min;  //比較
            }
            i++;
            j--;
        }
    }
}

(3)舉例
例1: 5 4 3 2 1 6 7
共7個元素。設max = min = a[0] = 5, i = 1
第一次比較a[1] = 4 < a[6] = 7, 第二次比較a[6] > max成立,max = a[6] = 7,第三次比較a[1] < min成立,min = a[1] = 4
第四次比較,a[2] = 3 < a[5] = 6, 第五次比較a[5] > max不成立,第六次比較a[2] < min成立,min = a[2] = 3
第七次比較,a[3] = 2 > a[4] = 1,第八次比較a[3] > max不成立,第九次比較a[4] < min成立,min = a[4] = 1。
總共比較了9次,9 = 向上取整(3 * 7)/ 2 - 2 = 11 - 2
例2: 1 2 3 4 5 6
共6個元素。第一次比較a[0] < a[1], min = a[0] = 1, max = a[1] = 2, i = 2
第二次比較a[2] = 3 < a[5] = 6, 第三次比較a[5] > max成立,max = a[5] = 6,第四次比較a[1] < min成立,min = a[1] = 4
第五次比較,a[3] = 4 < a[4] = 5, 第六次比較a[4] > max不成立,第七次比較a[3] < min不成立。
總共比較了7次,7 = 向上取整(3 * 6)/ 2 - 2

10 B
故事包含故事。函式呼叫函式。

11 A
連通圖:每兩個點之間,都有路徑可以到達
簡單圖:沒對頂點之間只能存在一條邊,且不包含環。

11.png

上面六個圖符合題意,下面三個圖不符合題意,因為包含了環。

12 B
10個元素的全部子集數為
C(10, 0) + C(10, 1) + C(10, 2) + C(10, 3) + C(10, 4) + C(10, 5) + C(10, 6) + C(10, 7) + C(10, 8) + C(10, 9) + C(10, 10)
= 2[C(10, 0) + C(10, 1) + C(10, 2) + C(10, 3) + C(10, 4)] + C(10, 5)
= 1024
這裡C(10, 0)表示空子集,空子集是任意非空集合的子集。C(10, 10)表示集合本身,集合本身也是集合的子集。
從10個元素裡取7個,有C(10, 7) = C(10, 3) = 120種方法。
120 / 1024 = 15 / 128

注,利用牛頓二項式定理,可以快速計算出C(10, 0) + C(10, 1) + … + C(10, 10)
牛頓二項式定理:
(a + b)10 = C(10, 0)a10-0b0 + C(10, 1)a10-1b1 + C(10, 2)a10-2b2 + … + C(10,10)a10-10b10
令a = b = 1,則有
210 = C(10, 0) + C(10, 1) + C(10, 2) + … + C(10, 10)

13 B
偶數都不能與10000互質。1~10000中的偶數有5000個。
能被5整除的數也不能與10000互質。1~10000中能被5整除的數有2000個,但是這2000箇中有一半也能被10整除,能被10整除就能被2整除,已經減過了,不能重複減。
所以10000 - 5000 - 2000/2 = 4000

14 B
這種題如果不會做,每個答案可以舉三個數來列舉。
這些數要有獨特的特徵,既要考慮特殊性,也要考慮一般性。
第一個數裡面全是1,比如“111”。
第二個數裡只有最高位是1,其他位都是0,比如“100”。
第三個數裡1和0各個一半,比如“1010”。

A答案,x >>= 1,是表示x右移1位,即變為原來的一半。
例1:111
第一次迴圈,ret = 1, x = 11
第二次迴圈,ret = 2, x = 1
第三次迴圈,ret = 3, x = 0,迴圈結束
例2:100
第一次迴圈,ret = 1, x = 10
第二次迴圈,ret = 2, x = 1
到這裡可以看出A答案肯定是錯的。

B答案,x &= x - 1,表示x與x - 1取與後,把結果賦給x
例1:111
第一次迴圈,ret = 1, x = 110
第二次迴圈,ret = 2, x = 010
第三次迴圈,ret = 3, x = 0
例2:100
第一次迴圈,ret = 1, x = 0,迴圈結束
例3:1010
第一次迴圈,ret = 1, x = 1000
第二次迴圈,ret = 2, x = 0迴圈結束
三個例子都是對的,是正確答案的概率很大。但也不能斷定,因為只要能找到一個反例,就說明這個答案不對。所以要看剩下的兩個答案。

C答案: x |= x >> 1,表示把x與x的一半求或運算的結果賦值給x
例1:111
第一次迴圈,ret = 1, x = 111,出現死迴圈

D 答案:x << 1表示x變為原來的兩倍,肯定不對。此時確定答案為B。

15 B
棧的特點是先入後出,後入先出。

二、問題求解


欲購完整答案請加微信307591841
瞭解小朋友學程式設計請加QQ群581357582
關注公眾號請掃描二維碼
qrcode_for_kidscode_258.jpg