NOIP2018普及初賽解析


今年難度大了很多,也有很多毒瘤題..

這篇博客嘗試詳盡地解析NOIP2018普及初賽.

題目

 

答案

先附上答案

 

單項選擇題

1.C

送分題 其他都是輸入設備

2.D

A: $(269)_{16}=617$

B: $617$

C: $(1151)_{8}=617$

D: $(1001101011)_{2}=619$

3.D

常識性知識

$1GB=1024KB=1024*1024B$

4.A

廣域網-Wide Area Network-WAN

想Wide就可以了

5.B

CCF贊歌,最近幾乎每年都有。

直接拿今年年份減去屆數(2018-24=1984)。

6.A

小學奧數。在歷年的基礎上改了下。每8個字母($ASDFasdf$)一個循環,$81%8=1$,所以為A.

7.A

可以正經推出。但考試的時候如果不知道那可以畫幾個例子,然后帶進去算。算出來A為正確。

注意本題樹根深度記做0.

8.A

基數排序就是桶排序,所以不用比較。

沒聽說過?

B.冒泡和D.插入一定知道吧,都需要對比。C.堆排,堆的數據插入后上浮下沉操作需要比對,所以排除法選A。

9.A

看題目首先排除C和D。

然后時間復雜度一般要考慮最壞所以向上取整(然而我還是錯了)。

10.B

送分。

11.C

分類討論。

如下所示:

         

 

12.B

注意空集

13.B

小學奧數,分解質因數$10000=2^4*5^4$,2的倍數有4999個,5的倍數有1999個,除去10(2和5的公倍數)999個,加上10000這一個數,不互質的就是6000個,互質的就是10000-6000=4000個

14.B

狀壓DP常規操作,實在不行模擬也可。

15.B

不用多說,先進先出,棧。

問題求解

1

小學奧數,從③推出丁不去,又從④推出甲去了,然后由①推出沒下雨。

2

分類討論。

1-9中:1個

10-99中:1*8+10=18個

100-999中:(1+18)*8+100=252個

1000-1999中:1+18+252=271個

2000-2018中:2個

總共 1+18+252+271+2=544個

注意最后的2個要加上去,我是不會說我沒加的

閱讀程序寫結果

1

#include <cstdio>
char st[100];
int main() {
    scanf("%s", st);
    for (int i = 0; st[i]; ++i) {
        if ('A' <= st[i] && st[i]<= 'Z')
            st[i] += 1;
    }
    printf("%s\n", st);
    return 0;
}

讀題意就是將所有大寫字母變成字母后一位,如'A'變成'B','E'變成'F'.

輸出:RuanHuoMianTai

2

#include <cstdio>
int main() 
    int x;
    scanf("%d",&x);
    int res = 0;
    for (int i=0;i<x;++i) {
        if (i*i%x == 1) {
            ++res;
        }
    }
    printf("%d", res);
    return 0;
}

讀題意得 0-15 每一個數的平方模15 是不是等於1

枚舉和模的時候要細心

輸出:4

3

#include <iostream>
using namespace std;
int n,m;
int findans(int n,int m){
    if (n==0) return m;
    if (m==0) return n % 3;
    return findans(n-1,m)-findans(n,m-1)+findans(n-1,m-1);
}
int main(){
    cin>>n>>m;
    cout<<findans(n,m)<<endl;
    return 0;
}

做的時候暴力模擬,后來知道可以用表格。

$f[i][j]=f[i-1][j]-f[i][j-1]+f[i-1][j-1]$

表格長這樣

 

n/mn/m 0 1 2 3 4 5 6
0 0 1 2 3 4 5 6
1 1 0 3 2 5 4 7
2 2 -1 4 1 6 3 8
3 0 1 2 3 4 5 6
4 1 0 3 2 5 4 7
5 2 -1 4 1 6 3 8

輸出:8

4

#include <cstdio>
int n,d[100];
bool v[100];
int main(){
    scanf("%d",&n);
    for (int i=0;i<n;++i) {
        scanf("%d",d+i);
        v[i]=false;
    }
    int cnt=0;
    for (int i=0;i<n;++i) {
        if (!v[i]){
            for (int j=i;!v[j];j=d[j]) {
                v[j]=true;
            }
        ++cnt;
        }
    }
    printf("%d\n", cnt);
    return 0;
}

暴力模擬即可

輸出:6

完善程序

1.最大公約數之和

(1)

$i*i$,枚舉到$\sqrt{n}$

(2)

$n/i$

(3)

return a

(4)

a%b

(5)

gcd(a[i],a[j])+ans

2.雙向鏈表求排列

(1)

a[x]=i

(2)

i+1

(3)

R[a[i]],對稱填

(4)

a[i],剛開始對稱填錯了,雙向鏈表操作

(5)

R[i]


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM