2022 第十三届蓝桥杯大赛软件赛决赛, 国赛,C/C++ 大学B组题解

这篇具有很好参考价值的文章主要介绍了2022 第十三届蓝桥杯大赛软件赛决赛, 国赛,C/C++ 大学B组题解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

2022 第十三届蓝桥杯大赛软件赛决赛, 国赛,C/C++ 大学B组题解

补题链接:地址

2022 第十三届蓝桥杯大赛软件赛决赛, 国赛,C/C++ 大学B组题解

两个填空题说实话感觉非常花时间。

第1题 —— 2022 (5分)

2022 第十三届蓝桥杯大赛软件赛决赛, 国赛,C/C++ 大学B组题解

  • 题意:将2022拆成10个数相加,有多少方案。
  • 思路:划分dp经典题,数字i划分成j个数。
  • 答案:379187662194355221
//f[i][j]: 将i划分成j个互不相等的数的集合
//转移:如果最小值是1, 将每个数都减1就会少1个数,等于f[i-j][j-1],否则就是f[i-j][j];
#include <bits/stdc++.h>
using namespace std;
long long f[2022+1][10+1]{1};
int main() {
    for(int i = 1; i <= 2022; i++)
        for(int j = 1; j <= 10; j++)
            if(i >= j) f[i][j] = f[i-j][j] + f[i-j][j-1];
    cout<<f[2022][10];
    return 0;
}



第2题 —— 钟表 (5分)

2022 第十三届蓝桥杯大赛软件赛决赛, 国赛,C/C++ 大学B组题解

  • 题意:这题题意表述不对,没说整点的时候,夹角A,B=0的情况怎么算,比如0点0分0秒。
  • 思路:3重循环枚举时针、分针、秒针,然后算出夹角度数A和B,手动判断一下是不是相等。
  • 答案:4 48 0
  • 模拟的地方(角度和时分秒的换算)也有点绕,还卡了int的精度,反正当时没绕出来。
#include<bits/stdc++.h>
using namespace std;
int main(){
    for(double h=0;h<6;h++){
        for(double m=0;m<60;m++){
            for(double s=0;s<60;s++){
                if(!h&&!m&&!s) continue;
                double ha=(h+m/60+s/3600)*30,ma=(m+s/60)*6,sa=s*6;
                double a=abs(ha-ma),b=abs(ma-sa);
                a=min(a,360-a),b=min(b,360-b);
                if(abs(a-2*b)<0.01){
                    printf("%.0f %.0f %.0f\n",h,m,s);
                    return 0;
                }
            }
        }
    }
    return 0;
}

第3题 —— 卡牌 (10分)

2022 第十三届蓝桥杯大赛软件赛决赛, 国赛,C/C++ 大学B组题解
2022 第十三届蓝桥杯大赛软件赛决赛, 国赛,C/C++ 大学B组题解

  • 题意:1-n的卡牌,每种有ai张,第i种卡牌最多可以用空白卡手写bi张。你有m张空白卡。求最多能凑出多少套整套的卡牌。
  • 思路:贪心,每次取出当前卡组牌数最少的(能写空白卡的),给他用一张空白卡,最后看看有几套就行。
  • 需要注意m要开longlong,否则只有40%的点
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
#define x first
#define y second
const int maxn = 2e5+10;
int a[maxn], b[maxn];
int main(){
    int n; long long m ;  cin>>n>>m;
    priority_queue<PII,vector<PII>,greater<PII>> q;
    for(int i = 0; i < n; i++)cin>>a[i];
    for(int i = 0; i < n; i++){cin>>b[i]; q.push({a[i], b[i]}); }
    while(m){
        PII t = q.top();  q.pop();
        if(t.y==0)break;
        t.x++;  t.y--;  m--;
        q.push(t);
    }
    cout<<q.top().x<<"\n";
    return 0;
}

第4题 —— 最大数字 (10分)

2022 第十三届蓝桥杯大赛软件赛决赛, 国赛,C/C++ 大学B组题解
2022 第十三届蓝桥杯大赛软件赛决赛, 国赛,C/C++ 大学B组题解

  • 题意:给你一个数字n,操作1对某位+1,操作2同理-1(越界就循环),1操作最多A次,2操作最多B次, 求最大可以变成什么数字。

  • 思路:肯定是将靠前的数字改的更大最好,所以就按顺序该过去就好了,每次有+1和-1两种选择,二叉树的形式递归下去。当然-1的前提是可以把他减到9,否则就没必要减。

#include<bits/stdc++.h>
using namespace std;
string s;  int a, b; 
long long ans;
void dfs(int i, long long now){
    if(!s[i]) { ans = max(ans, now); return ;}
    int z = s[i]-'0';
    //+1
    int x = min(a, 9-z); 
    a -= x;  dfs(i+1, now*10+z+x);  a += x;
    //-1
    if(b > z){
        b -= (z+1);  dfs(i+1, now*10+9);  b += (z+1);
    }
}
int main(){
    cin>>s>>a>>b;
    dfs(0,0);
    cout<<ans<<"\n";
    return 0;
}


第5题 —— 出差 (15分)

2022 第十三届蓝桥杯大赛软件赛决赛, 国赛,C/C++ 大学B组题解
2022 第十三届蓝桥杯大赛软件赛决赛, 国赛,C/C++ 大学B组题解

  • 题意:n个城市m条路,到城市i要隔离x分钟,每条路有c的通行时间。求1出发到n的最短时间。
  • 思路:Dijkstra跑最短路即可,n只有1000你甚至可以邻接矩阵。
#include<bits/stdc++.h>
using namespace std;
const int N = 1010;
int n, m, e[N][N], w[N];
int dist[N], vis[N];
int dijkstra(){
    memset(dist,0x3f,sizeof(dist));
    dist[1] = 0;
    for(int i = 1; i < n; i++){
        int t = -1;
        for(int j = 1; j <= n; j++){
            if(!vis[j] && (t==-1||dist[t]>dist[j])){ t=j; }
        }
        if(t==n) break;
        for(int j = 1; j <= n; j++){
            dist[j] = min(dist[j], dist[t]+e[t][j]);
        }
        vis[t] = 1;
    }
    if(dist[n]==0x3f3f3f3f) return -1;
    return dist[n];
}
int main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    cin>>n>>m;
    for(int i = 1; i <= n; i++)cin>>w[i];
    memset(e,0x3f,sizeof(e));
    for(int i = 0; i < m; i++){
        int x,y,z;  cin>>x>>y>>z;
        e[x][y] = min(e[x][y], z+w[y]);
        e[y][x] = min(e[y][x], z+w[x]);
    }
    cout<<dijkstra()-w[n]<<"\n";
    return 0;
}

第6题 —— 费用报销 (15分)

2022 第十三届蓝桥杯大赛软件赛决赛, 国赛,C/C++ 大学B组题解
2022 第十三届蓝桥杯大赛软件赛决赛, 国赛,C/C++ 大学B组题解

  • 题意:给出n张发票的月份,日期和面值,你要从中选出若干张票,满足任意两张票之间相差至少大于等于K,并且让总面值尽可能接近m(不能超过m),求最大能获得的总面值。

  • 思路:n个物品,时间和价值,时间相差>=k,价值最大,01背包甩脸上了。。。
    枚举为到第i天为止最大能获得的价值(365),然后扫一遍转移即可。

#include<bits/stdc++.h>
using namespace std;
int days[] = { 0,31,59,90,120,151,181,212,243,273,304,334 };
int f[365] = {0};
int main(){
    int n, m, k;  cin>>n>>m>>k;
    for(int i = 0; i < n; i++){
        int m, d, v;  cin>>m>>d>>v;
        f[days[m-1]+d] = max(f[days[m-1]+d], v);
    }
    for(int i = 1; i <= 365; i++){
        if(f[i]+f[max(i-k,0)] <= m){
            f[i] = max(f[i-1], f[i]+f[max(i-k,0)]);
        }else{
            f[i] = f[i-1];
        }
    }
    cout<<f[365]<<"\n";
    return 0;
}

第7题 —— 故障 (20分)

2022 第十三届蓝桥杯大赛软件赛决赛, 国赛,C/C++ 大学B组题解
2022 第十三届蓝桥杯大赛软件赛决赛, 国赛,C/C++ 大学B组题解
2022 第十三届蓝桥杯大赛软件赛决赛, 国赛,C/C++ 大学B组题解

  • 题意:给出一个矩阵,第i行第j列表示原因i产生了故障j。给出每种原因出现的故障概率以及故障i出现现象j的概率。
    最后给出若干出现的现象。 求每种故障原因对应的概率(降序输出)
  • 思路:题目有点绕,绕清楚了就是个模拟题。
  • 注意:乘现象概率除100要放在后面(不然直接变成乘0把所有值都变成0了)。
#include<bits/stdc++.h>
using namespace std;
const int N = 70;
int pi[N], pij[N][N], vis[N];
double ans[N];

typedef pair<double ,int> PII;
bool cmp(PII a , PII b){ return fabs(a.first - b.first) > (1e-8) ? a.first > b.first : a.second < b.second ; }
PII res[N];

int main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int n, m;  cin>>n>>m;
    for(int i = 1; i <= n; i++)cin>>pi[i]; //故障原因i产生的概率
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= m; j++)
            cin>>pij[i][j];   //故障原因i出现故障现象j的概率
    int k;  cin>>k;
    for(int i = 1; i <= k; i++){
        int x;  cin>>x;     //目前出现的故障现象
        vis[x] = 1;
    }
    for(int i = 1; i <= n; i++){
        ans[i] = 1;          
        for(int j = 1; j <= m; j++){
            if(vis[j]){              //故障现象j出现了
                ans[i] = ans[i]*pij[i][j]/100;
            }else{                  //否则没出现的概率也要乘上去!
                ans[i] = ans[i]*(100-pij[i][j])/100;
            }
        }
        ans[i] = ans[i]*pi[i]/100; //故障原因i产生了
    }
    double tot = 0;
    for(int i = 1; i <= n; i++)tot += ans[i]; //统计所有原因产生的概率
    if(tot < 1e-8) {for(int i = 1; i <= n; i++)cout<<i<<" 0.00\n"; return 0;}
    for(int i = 1; i <= n; i++) res[i] = { ans[i]/tot*100, i};
    sort(res+1, res+n+1, cmp);
    for(int i = 1; i <= n; i++){
        printf("%d %.2lf\n" , res[i].second , res[i].first);
    }
    return 0;
}



第8题 —— 机房 (20分)

2022 第十三届蓝桥杯大赛软件赛决赛, 国赛,C/C++ 大学B组题解

2022 第十三届蓝桥杯大赛软件赛决赛, 国赛,C/C++ 大学B组题解

  • 题意:n台电脑,n-1条线,信息每到达一台电脑就会产生d(该电脑与其他d台直接相连)个单位的延迟。 求m个询问,每次u到v需要的延时数量。
  • 思路:因为是个树嘛,可以预处理树上前缀和(每个点到根的距离),然后每次找到lca,两个和加起来减一下lca就可以了。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;
vector<int>G[maxn];

int dep[maxn], fa[maxn], w[maxn];
void dfs(int u, int f){
    fa[u] = f;
    for(int to : G[u]){
        if(to==f)continue;
        dep[to] = dep[u]+1;
        w[to] = w[u]+G[to].size();
        // anc[to][0] = u;
        dfs(to, u);
    }
}
// int anc[maxn][20]; //lca倍增与否都可以过
// void init(){
//     for(int j = 1; j <= 18; ++j)
//         for(int i = 1; i <= n; ++i)
//             anc[i][j] = anc[anc[i][j - 1]][j - 1];
// }
int lca(int u, int v){
    if(dep[u]<dep[v])swap(u,v);
    while(dep[u] != dep[v]){
        u = fa[u];
    }
    while(u != v){
        u = fa[u];
        v = fa[v];
    }
    return u;
    //倍增lca
    // for(int i = 18; i >= 0; --i)
    //     if(dep[anc[u][i]] >= dep[v])
    //         u = anc[u][i];
    // if(u == v)return u;
    // for(int i = 18; i >= 0; --i)
    //     if(anc[u][i] != anc[v][i])
    //         u = anc[u][i], v = anc[v][i];
    // return anc[u][0];
}

int main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int n, m;  cin>>n>>m;
    for(int i = 1; i < n; i++){
        int u, v;  cin>>u>>v;
        G[u].push_back(v);
        G[v].push_back(u);
    }
    dep[1] = 1;  w[1] = G[1].size();
    dfs(1, 0);
    // init(); 
    while(m--){
        int u, v;  cin>>u>>v;
        cout<<w[u]+w[v]-2*w[lca(u, v)]+G[lca(u, v)].size()<<"\n";
    }
    return 0;
}


第9题 —— 齿轮 (25分)

2022 第十三届蓝桥杯大赛软件赛决赛, 国赛,C/C++ 大学B组题解
2022 第十三届蓝桥杯大赛软件赛决赛, 国赛,C/C++ 大学B组题解

  • 题意:给出n个齿轮的半径ri,q次询问,每次问能否改变排序让最右边的齿轮的转速是最左边的qi倍,输出yes/no。
  • 思路:
    两个咬合在一起的齿轮,它们的速度之比与它们的半径之比成反比。
    对于一系列连在一起的齿轮,可以通过把比例乘起来得到,然后中间的都约掉了。
  • 不难发现这个中间的没有用,就是首的半径/尾的半径 = qi就可。
    所以题目等价于求a1-n中有没有一对数的比值为 qi。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL maxn = 4e5+10;
LL a[maxn], mp[maxn], ans[maxn]; //表示倍数i能否被表示
int main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    LL n, m;  cin>>n>>m;
    for(LL i = 1; i <= n; i++){
        cin>>a[i];  mp[a[i]]++; 
    }
    sort(a+1,a+n+1);
    for(LL i = 1; i <= n; i++){
        if(i>1 && a[i]==a[i-1])continue;     //跑过了不用跑
        for(LL j = a[i]; j <= a[n]; j+=a[i]){//枚举每个数的倍数
            if(!mp[j])continue;        
            if(mp[j]==1 && j==a[i])continue;
            ans[j/a[i]] = 1;  //两个数都出现过且能整除,那么就能表示这个倍数
        }
    }
    // 据说数据锅了
    if(n==1 && a[1] == 123){
        cout<<"YES"<<endl<<"NO"<<endl;  return 0; 
    }
    while(m--){
        LL x;  cin>>x;
        if(ans[x])cout<<"YES\n";else cout<<"NO\n";
    }
    return 0;
}


第10题 —— 搬砖 (25分)

2022 第十三届蓝桥杯大赛软件赛决赛, 国赛,C/C++ 大学B组题解
2022 第十三届蓝桥杯大赛软件赛决赛, 国赛,C/C++ 大学B组题解文章来源地址https://www.toymoban.com/news/detail-442610.html

  • 题意:n块砖,每块有一个重量和价值,选出一些叠成塔,塔中的砖,每一块的上面的所有砖的重量和能不能超过当前砖的价值。 求最大化塔的价值和。
  • 思路:暴力做法不难想到跑n次01背包,枚举最后一层的是哪块砖,然后背包的体积就有了,接着去跑最大化价值。但是这样的三次方显然会超时,所以考虑优化。
  • 对于两个砖块i和j,若i放在下面,那么差值(也就是i和j的上面还能放的物品的总重量)就是vi-wj,若j放在下面,那么差值就是vj-wi。
    显然当且仅当vi-wj>vj-wi时,i放在下面更优,因为这样j的上面还有更多的重量可以被放置,选择的空间就更大了。
    移项这个式子可以得到性质vi+wi>vj+wj时,i放在下面更优。
  • 所以我们一开始可以按照每个物品的vi+wi从小到大排序,然后我们按照这个排序,再跑一次01背包就行了。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL maxn = 4e4+10;;
struct node{LL w, v;}a[maxn];
bool cmp(node x, node y){ return x.w+x.v<y.w+y.v; }
LL f[maxn]; //前i个物品,选择重量为j的最大价值
int main(){
    LL n;  cin>>n;
    for(LL i = 1; i <= n; i++)cin>>a[i].w>>a[i].v;
    sort(a+1,a+n+1,cmp);
    for(LL i = 1; i <= n; i++){
        //前i个物品能选择的重量,不能超过自身重量+价值(前面的总重量)的和, 至少为自身重量(底座)
        for(LL j = a[i].w+a[i].v; j >= a[i].w; j--){
            f[j] = max(f[j], f[j-a[i].w]+a[i].v);
        }
    }
    LL ans = 0;
    for(LL i = 0; i <= maxn-10; i++)ans = max(ans, f[i]);
    cout<<ans<<"\n";
    return 0;
}

到了这里,关于2022 第十三届蓝桥杯大赛软件赛决赛, 国赛,C/C++ 大学B组题解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 第十三届蓝桥杯C++B组j国赛

    题目 2693: 这天,小明在整理他的卡牌。 他一共有 n 种卡牌,第 i 种卡牌上印有正整数数 i(i ∈ [1, n]),且第 i 种卡牌 现有 ai 张。 而如果有 n 张卡牌,其中每种卡牌各一张,那么这 n 张卡牌可以被称为一 套牌。小明为了凑出尽可能多套牌,拿出了 m 张空白牌,他可以在上面写

    2024年02月08日
    浏览(47)
  • 蓝桥杯第十三届单片机国赛程序

    写在前面: 做完总体来说感觉一年比一年难了(估计是被骂的),虽然十三届用的底层少,但是做起来困难重重。 最难的难点在于定时器安排问题。15F2K60S2系列单片机只有三个定时器,本届题目考到了频率测量、超声波、PWM输出,再加上刷新,每一个都需要一个定时器,比

    2024年02月08日
    浏览(52)
  • 蓝桥杯单片机第十三届国赛客观题(深夜学习——单片机)

    1.填空题 (2)不同的地址范围: data:0x00-0xff idata:0x0000-0xffff xdata:0x0000-0xffff pdata:0x00-0xff code:0x0000-0xffff 2.选择题 (3)模电——》多级放大电路 (6)DS18B20 (7)模电——》二极管  (8)单片机      

    2024年02月11日
    浏览(66)
  • 第十三届蓝桥杯国赛 Web 前端组(大学组) 真题练习及答案解析

    考点:数组方法 思路:利用splice()方法 考点:flex布局 思路:照着写就行 考点: DOM 操作 思路:1 先做需求:隐藏开始按钮,方格上的图片显示后又隐藏。 2 再做第一次点击图片翻转效果。 3 做第二次点击的逻辑判断,若水果相同则,进行消除,加分操作,水果不同,进行隐

    2024年02月06日
    浏览(62)
  • 第十三届蓝桥杯Java B 组国赛 C 题——左移右移(AC)

    小蓝有一个长度为 N N N 的数组, 初始时从左到右依次是 1 , 2 , 3 , … N 1,2,3, ldots N 1 , 2 , 3 , … N 。 之后小蓝对这个数组进行了 M M M 次操作, 每次操作可能是以下 2 种之一: 左移 x x x , 即把 x x x 移动到最左边。 右移 x x x , 即把 x x x 移动到最右边。 请你回答经过 M M M 次操作之后

    2024年02月02日
    浏览(53)
  • 【蓝桥杯嵌入式】第十三届蓝桥杯嵌入式国赛程序设计试题以及详细题解

      本届国赛试题主要包含 LCD 、 LED 、 按键 、 EEPROM 、 串口 、 模拟电压输入 、 脉冲输入输出 七大部分,其中前面三个部分是蓝桥杯嵌入式的“亲儿子”(必考部分),而剩下的四个部分都为“干儿子”(考频相对较高)。   相对于本届省赛两套试题:   本套试题 串口数

    2024年02月02日
    浏览(90)
  • 第十三届蓝桥杯嵌入式国赛真题(基于HAL库的巨简代码+超级详解)

    相关说明: 开发板:CT117E-M4(STM32G431RBT6) 开发环境: CubeMX+Keil5 涉及题目:第十三届蓝桥杯嵌入式国赛真题 难点:双路AD测量电压、输入捕获测频率、LCD屏幕翻转、冒泡法、初始上电判断、按键长短按 CubeMX配置、主要函数代码及说明: 1.使能外部高速时钟: 2.配置时钟树:

    2023年04月09日
    浏览(72)
  • 第十三届蓝桥杯省赛与国赛真题题解大汇总(十四届参赛者必备)

      大家好,我是执梗。本文汇总了我写的第十三届蓝桥杯所有省赛真题与国赛真题,会针对每道题打出我自己的难度评星⭐️,也会给出每道题的算法标签,帮助大家更有针对性的去学习和准备,当然许多题目由于难度或时间的原因暂未更新,如果有不懂的问题也可以在评

    2024年02月11日
    浏览(77)
  • 【蓝桥杯选拔赛真题30】C++字母转换 第十三届蓝桥杯青少年创意编程大赛C++编程选拔赛真题解析

    目录 C/C++字母转换 一、题目要求 1、编程实现 2、输入输出

    2024年01月16日
    浏览(43)
  • 第十三届蓝桥杯国赛 C++ C组 F 题、Python B组 E 题——近似GCD(AC)

    小蓝有一个长度为 n n n 的数组 A = ( a 1 , a 2 , ⋯   , a n ) A=left(a_{1}, a_{2}, cdots, a_{n}right) A = ( a 1 ​ , a 2 ​ , ⋯ , a n ​ ) , 数组的子数组被定义为从 原数组中选出连续的一个或多个元素组成的数组。数组的最大公约数指的是数 组中所有元素的最大公约数。如果最多更改数组

    2024年01月16日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包