2019年第十屆藍橋杯C/C++ B組省賽題解


試題A——組隊

 

 

直接手算,注意一位球員只能擔任一個位置

 

 答案:490

 

試題B——年號字串

 

 將十進制轉換為26進制

#include<bits/stdc++.h>
using namespace std;
char str[27] = {0,'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
int main(){
    int num;
    string ans = "";
    scanf("%d",&num);
    while(num){
        ans += str[num%26];
        num /= 26;
    }
    for(int i = ans.size() - 1; i >= 0; --i){
        cout<<ans[i];
    }
    return 0;
} 

答案:BYQ

試題C——數列求值

 

 斐波那契數列變形題,難點是數據過大,超出了long long ,因此對每一步mod10000.

 

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int mod = 1e4;
LL dp[20190325];
int main(){
    dp[1] = dp[2] = dp[3] = 1;
    for(int i = 4;i <= 20190324; ++i){
        dp[i] = (dp[i - 1] + dp[i - 2] + dp[i - 3]) % mod;
    }
    cout<<dp[20190324]<<endl;
    return 0;
}

答案:4659

試題D——數的分解

 

 枚舉,結果是一組a,b,c三個數,相同數的不同排列視為同一種,三個數總共有6種排列,因此結果要除以6

時間復雜度為2019^3,,結果要等待一會

#include<bits/stdc++.h>
using namespace std;
bool check(int x, int y, int z){
    int res = 0;
    while(x){
        res = x % 10;
        if(res == 2 || res == 4) return false;
        x /= 10; 
    }
    while(y){
        res = y % 10;
        if(res == 2 || res == 4) return false;
        y /= 10; 
    }
    while(z){
        res = z % 10;
        if(res == 2 || res == 4) return false;
        z /= 10; 
    }
    return true;
}
int main(){
    int ans = 0;
    for(int a = 1; a < 2019; ++a){
        for(int b = 1; b < 2019; ++b){
            if(b == a) continue;
            for(int c = 1; c < 2019; ++c){
                if(a == c || b == c) continue;
                if(a + b + c == 2019 && check(a,b,c)) ans++;
            }
        }
    }
    cout<<ans/6<<endl;
    return 0;
}

答案:40785

試題E——迷宮

 

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

 這題當時沒做出來,參考了博主Acmer-ly的答案。

題目是求最短路徑,很容易就想到用BFS,在結構體中添加一個字符串,記錄每次前進的方向,

#include<bits/stdc++.h>
using namespace std;
char mp[30][50];
bool vis[30][50];
int dir[4][2] = {{1,0},{0,-1},{0,1},{-1,0}};//按照下,左,右,上的順序走
char dirc[4] = {'D','L','R','U'};
int n,m;
struct node{
    int x;
    int y;
    int step;
    string str;
    node(int xx, int yy, int ss,string s){//構造函數 
        x = xx;
        y = yy;
        step = ss;
        str = s;
    }
}; 
queue<node> q; //創建隊列
bool check(int x, int y){//判斷是否越界、是否是牆、是否被訪問過了 
    if(x < 0|| x >= n || y < 0 || y >= m || vis[x][y] ||mp[x][y] == '1'){
        return false;
    }
    return true;
} 

void bfs(int x, int y){
    q.push(node(x, y, 0, ""));
    vis[x][y] = true;
    while(!q.empty()){
        node now = q.front();
        if(now.x == n - 1&&now.y == m - 1){//到達終點了 
            cout<<now.str<<endl;
            cout<<now.step<<endl;
            break;
        } 
        q.pop();
        for(int i = 0;i < 4; i++){
            int nx = now.x + dir[i][0];
            int ny = now.y + dir[i][1];
            if(check(nx, ny)){
                q.push(node(nx, ny,now.step + 1, now.str + dirc[i]));
                vis[nx][ny] = true;
            }
        }
    }
}
int main(){
    scanf("%d%d",&n, &m);
    for(int i = 0;i < n; i++){
        scanf("%s",mp[i]);
    }
    bfs(0, 0);
    return 0;
}

試題F——特別數的和

 

 

 水題,枚舉判定即可

 

#include<bits/stdc++.h>
using namespace std;
int check(int i){
    int k = 0;
    while(i){
        k = i%10;
        if(k == 2||k == 0||k == 1||k == 9) return true;
        i/=10;
    }
    return false;
    
}
int main(){
    int n;
    scanf("%d",&n);
    int ans = 0;
    for(int i = 1;i <= n;++i){
        if(check(i)){
            ans += i;
        }
    }
    cout<<ans<<endl;
    return 0;
}

試題G——完全二叉樹的權值

 

 

 

 

 

 

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
int main(){
    int n;
    cin>>n;
    LL maxv = INT_MIN;//最大權值和 
    LL maxd = 0;
    for(int i = 0,length = 1,depth = 1;i < n;depth++,length *= 2 ){//逐層計算 
        LL sum = 0;
        for(int j = 0; j < length&&i < n; j++,i++){
            int x;
            cin>>x;
            sum+=x;
        } 
        if(sum > maxv){
            maxv = sum;
            maxd = depth;
        }
    }
    cout<<maxd<<endl;
    return 0;
}

無需建樹,邊輸入邊計算,保留最大權值和的層數,

試題H——等差數列

 

 

 使用gcd求出最大公約數,再根據公式a[n] - a[1] /d + 1求出等差數列長度。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 1e5;
LL a[maxn];
int gcd(int a, int b){
    return !b ? a : gcd(b, a % b);
}
int main(){
    int n;
    scanf("%d",&n);
    for(int i = 1;i <= n; ++i){
        scanf("%d",&a[i]);
    }
    sort(a+1,a+n+1);
    for(int i = 2;i <= n; ++i){
        a[i] -= a[1];
    }
    int d = a[2];
    for(int i = 3; i <= n; ++i){
        d = gcd(d, a[i]);
    }
    if(d == 0){
        cout<<n<<endl;
    }else{
        cout<<a[n] / d + 1<<endl;
    }
    return 0;
}

試題I——后綴表達式

 

 

 試題J——靈能傳輸

 

 

 

 


免責聲明!

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



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