2019年藍橋杯總結

今年的藍橋杯整體來說難度並不是特別大,但是對於細節的考察確實特別多。邏輯思維也是一個考察點,寫的時候一定要小心

一、組隊

作爲籃球隊教練,你需要從以下名單中選出 1 號位至 5 號位各一名球員,組成球隊的首發陣容。
每位球員擔任 1 號位至 5 號位時的評分如下表所示。請你計算首發陣容 1 號位至 5 號位的評分之和最大可能是多少?
在這裏插入圖片描述

思路

第一題,我們可以通過看題目筆算出來

答案:490

二、年號字串

小明用字母A 對應數字1,B 對應2,以此類推,用Z 對應26。對於27以上的數字,小明用兩位或更長位的字符串來對應,例如AA 對應27,AB 對應28,AZ 對應52,LQ 對應329。
請問2019 對應的字符串是什麼?

思路

第二題,我是直接讓2019對26取餘數得到最後一個字母
2019%26=17------------對應Q
讓2019對26取整 2019/26=77
我們知道z是一個26;zz是26個26;azz是52個26;bzz是78個26;52<77<78
那麼我們知道這個數一定是三位的,我們直接讓77對26取餘得到第二位上的字母
77%26=17------------對應Y
讓77對26取整 77/26=2
我們可以得到第一位上的字母
77/26=2------------對應B
所以是BYQ

答案:BYQ

三、數列求值

給定數列1, 1, 1, 3, 5, 9, 17, …,從第4 項開始,每項都是前3 項的和。求
第20190324 項的最後4 位數字。

思路

第三道題,感覺很像斐波那契,自己筆算肯定很費力,所以來跑段代碼吧
主要使用到的公式就是(a[i]+a[i+1]+a[i+2])%10000;
算出來答案是4659

4659

四、數的分解

把2019 分解成3 個各不相同的正整數之和,並且要求每個正整數都不包含數字 2 和 4,一共有多少種不同的分解方法?
注意交換3個整數的順序被視爲同一種方法,例如1000+1001+18 和 1001+1000+18 被視爲同一種。

思路

第四道題,也是需要用代碼來寫;我們定義這三個數分別爲i,j,k
說來慚愧,這道題我想到了用兩重循環來確定i,j,k得值,也想到i,j得值都應該小於2019/3=673.也想到了用while循環來判斷一個數中是否有2,4.
但是卡克的地方是我沒想到i<j<k的關係,
其實仔細想想,如果i=5了,j一定要從6開始取值,因爲1,2,3一定已經被i取過了,而且只要i,j得值小於2019/3=673,那麼k得值一定比他們兩個大三個數的值一定不會相同
下面來看一下代碼

#include<iostream>
#include<cstdio>
using namespace std;
bool yes(int x) {
    while(x!=0)
    {
        if (x % 10 == 2 || x % 10 == 4) return false;
        x/=10;
    }
    return true;
}
int main() {
    int N = 2019;
    int sum = 0;
    for (int i = 1; i < N / 3; ++i)
    {
        if (yes(i))
        {
             for (int j = i + 1; N - i - j > j; ++j)
             {
                 if (yes(j) && yes(N - i - j))
                    sum++;
             }

        }

    }
    printf("%d",sum);
    return 0;
}

答案:40785

五、 迷宮

下圖給出了一個迷宮的平面圖,其中標記爲1 的爲障礙,標記爲0 的爲可以通行的地方。

010000
000100
001001
110000

迷宮的入口爲左上角,出口爲右下角,在迷宮中,只能從一個位置走到這個它的上、下、左、右四個方向之一。
對於上面的迷宮,從入口開始,可以按DRRURRDDDR 的順序通過迷宮,一共10 步。其中D、U、L、R 分別表示向下、向上、向左、向右走。對於下面這個更復雜的迷宮(30 行50 列),請找出一種通過迷宮的方式,其使用的步數最少,在步數最少的前提下,請找出字典序最小的一個作爲答案。請注意在字典序中D<L<R<U。

01010101001011001001010110010110100100001000101010
00001000100000101010010000100000001001100110100101
01111011010010001000001101001011100011000000010000
01000000001010100011010000101000001010101011001011
00011111000000101000010010100010100000101100000000
11001000110101000010101100011010011010101011110111
00011011010101001001001010000001000101001110000000
10100000101000100110101010111110011000010000111010
00111000001010100001100010000001000101001100001001
11000110100001110010001001010101010101010001101000
00010000100100000101001010101110100010101010000101
11100100101001001000010000010101010100100100010100
00000010000000101011001111010001100000101010100011
10101010011100001000011000010110011110110100001000
10101010100001101010100101000010100000111011101001
10000000101100010000101100101101001011100000000100
10101001000000010100100001000100000100011110101001
00101001010101101001010100011010101101110000110101
11001010000100001100000010100101000001000111000010
00001000110000110101101000000100101001001000011101
10100101000101000000001110110010110101101010100001
00101000010000110101010000100010001001000100010101
10100001000110010001000010101001010101011111010010
00000100101000000110010100101001000001000000000010
11010000001001110111001001000011101001011011101000
00000110100010001000100000001000011101000000110011
10101000101000100010001111100010101001010000001000
10000010100101001010110000000100101010001011101000
00111100001000010000000110111000000001000000001011
10000001100111010111010001000110111010101101111000

思路

第五道題,深深地體現了我的基礎知識是有多麼的不牢固,我一看這道題,知道用深搜,但是怎麼打出路徑可真是把我弄蒙了,打了一個小時也沒琢磨出來,比賽完了看了大神的代碼:

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 100, MAXM = 100;
const int f[4] = { 1, 0, 0, -1 };
const int g[4] = { 0, -1, 1, 0 };
const char* s = "DLRU";
char a[MAXN][MAXM];
int r[MAXN][MAXM];
typedef pair<int, int> P;
int N, M;
void print(int x, int y) {
    if (x != 1 || y != 1) {
        int t = r[x][y];
        print(x - f[t], y - g[t]);
        cout << s[t];
    }
}
void solve() {
    queue<P> que; que.push(P(1, 1)); a[1][1] = '1';
    while (!que.empty()) {
        int x = que.front().first, y = que.front().second; que.pop();
        for (int i = 0; i < 4; ++i) {
            int nx = x + f[i], ny = y + g[i];
            if (a[nx][ny] == '0') {
                a[nx][ny] = '1';
                que.push(P(nx, ny));
                r[nx][ny] = i;
            }
        }
    }
    print(N, M);
}
int main() {
    //cin >> N >> M;
    N = 30, M = 50;
    memset(a, '1', sizeof(a));
    for (int i = 1; i <= N; ++i)
        scanf("%s", &a[i][1]);
    solve();
    return 0;
}

答案DDDDRRURRRRRRDRRRRDDDLDDRDDDDDDDDDDDDRDDRRRURRUURRDDDDRDRRRRRRDRRURRDDDRRRRUURUUUUUUULULLUUUURRRRUULLLUUUULLUUULUURRURRURURRRDDRRRRRDDRRDDLLLDDRRDDRDDLDDDLLDDLLLDLDDDLDDRRRRRRRRRDDDDDDRR

六、特別數的和

小明對數位中含有 2、0、1、9 的數字很感興趣(不包括前導0),在1 到 40 中這樣的數包括1、2、9、10 至 32、39 和 40,共 28 個,他們的和是 574。請問,在 1 到n 中,所有這樣的數的和是多少?

【輸入格式】
輸入一行包含兩個整數n。

【輸出格式】
輸出一行,包含一個整數,表示滿足條件的數的和。

【樣例輸入】
40

【樣例輸出】
574

【評測用例規模與約定】
對於20% 的評測用例,1≤n≤10 1 \leq n \leq 101≤n≤10。
對於50% 的評測用例,1≤n≤100 1 \leq n \leq 1001≤n≤100。
對於80% 的評測用例,1≤n≤1000 1 \leq n \leq 10001≤n≤1000。
對於所有評測用例,1≤n≤10000 1 \leq n \leq 100001≤n≤10000。

思路

第六題這道題也很簡單,直接暴力

#include<iostream>
#include<cstdio>
using namespace std;
int main() {
    int n,sum = 0,b,a;
    scanf("%d",&n);
    for (int i = 1; i <= n; i++)
    {
        b=i;
        a=0;
        while(b>0)
        {
            if(b % 10 == 2 || b % 10 == 0 || b % 10 == 1 || b % 10 == 9)
            {
                a=1;
                break;
            }
            b/=10;
        }
        if(a==1)
            sum+=i;
    }
    cout << sum << endl;
    return 0;
}

七、完全二叉樹的權值

給定一棵包含N 個節點的完全二叉樹,樹上每個節點都有一個權值,按從上到下、從左到右的順序依次是A1,A2,…,AN ,如下圖所示:
現在小明要把相同深度的節點的權值加在一起,他想知道哪個深度的節點權值之和最大?如果有多個深度的權值和同爲最大,請你輸出其中最小的深度。
注:根的深度是1。

【輸入格式】
第一行包含一個整數N。
第二行包含N 個整數A1,A2,…,AN

【輸出格式】
輸出一個整數代表答案。

【樣例輸入】
7
1 6 5 4 3 2 1

【樣例輸出】
2
【評測用例規模與約定】
在這裏插入圖片描述

思路

我們要知道,第i層所有數的個數是第(i-1)層所有數的個數的二倍
那麼,我只要定義一個量的,用來存第i層所有數的個數

代碼

#include <iostream>
#include <cstdio>
using namespace std;

int main()
{
    long long int n,i,j;
    long long int a,d,dp,mdp,sum,mmax;
    scanf("%lld",&n);
    d=1;
    j=1;
    sum=0;
    dp=1;
    mdp=1;
    for(i=1;i<=n;i++)
    {
        scanf("%lld",&a);
        if(i==1)
        {
            mmax=a;
        }
        sum+=a;
        if(i==j)
        {

            d*=2;
            j=i+d;
            if(mmax<sum)
            {
                mmax=sum;
                mdp=dp;
            }
            dp++;
            sum=0;
        }
    }
    cout << mdp << endl;
    return 0;
}

八、等差數列

數學老師給小明出了一道等差數列求和的題目。但是粗心的小明忘記了一部分的數列,只記得其中N 個整數。
現在給出這N 個整數,小明想知道包含這N 個整數的最短的等差數列有幾項?
【輸入格式】
輸入的第一行包含一個整數N。
第二行包含N 個整數A1,A2,…,AN 在這裏插入圖片描述
【輸出格式】
輸出一個整數表示答案。

【樣例輸入】
5
2 6 4 10 20

【樣例輸出】
10

【樣例說明】
包含2、6、4、10、20 的最短的等差數列是2、4、6、8、10、12、14、16、18、20。

【評測用例規模與約定】
在這裏插入圖片描述

思路:

排序+遍歷求兩數之差的最大公約數。

注意: d=0爲常數數列, 答案爲N

代碼

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int MAXN = 100000;
int N, a[MAXN];
int gcd(int a, int b) {
    return !b ? a : gcd(b, a % b);
}
int main() {
    scanf("%d", &N);
    for (int i = 0; i < N; ++i)
        scanf("%d", a + i);
    sort(a, a + N);
    int d = a[1] - a[0];
    if (d == 0) return printf("%d\n", d), 0;
    for (int i = 2; i < N; ++i)
        d = gcd(d, a[i] - a[i - 1]);
    printf("%d\n", (a[N - 1] - a[0]) / d + 1);
    return 0;
}

九、後綴表達式

給定N 個加號、M 個減號以及N + M + 1 個整數A1,A2,…,AM+N+1 ,小明想知道在所有由這 N 個加號、M 個減號以及 N + M +1 個整數湊出的合法的後綴表達式中,結果最大的是哪一個?
請你輸出這個最大的結果。
例如使用1 2 3 + -,則“2 3 + 1 -” 這個後綴表達式結果是4,是最大的。

【輸入格式】
第一行包含兩個整數N 和M。
第二行包含N + M + 1 個整數A1,A2,…,AM+N+1

【輸出格式】
輸出一個整數,代表答案。

【樣例輸入】
1 1
1 2 3
【樣例輸出】
4

代碼

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 100000;
const int MAXM = 100000;
const int INF = 0x3f3f3f3f;
int a[MAXN + MAXM + 1], N, M;
int main() {
    scanf("%d%d", &N, &M);
    int mini = INF;
    for (int i = 0; i <= N + M; ++i) {
        scanf("%d", a + i);
        mini = min(a[i], mini);
    }
    long long ret = 0;
    if (M) {
        for (int i = 0; i <= N + M; ++i)
            ret += abs(a[i]);
        if (mini > 0) ret -= mini * 2;
    }
    else for (int i = 0; i <= N + M; ++i)
        ret += a[i];
    cout << ret << endl;
    return 0;
}

最後兩道題的代碼實在是寫不下去了,看看大佬的吧。
最後一道題沒讀懂。。。。。
總結一下,坑太多了,一不小心入了好多坑,雖然感覺心裏很涼涼,但也發現了自己的不足,實在是不夠細心,哎以後還是要多努力,少點思維漏洞。希望下一年自己能夠加油,再接再厲。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章