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

news2025/4/4 17:36:12

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

文章目录

      • 第1题 —— 2022 (5分)
      • 第2题 —— 钟表 (5分)
      • 第3题 —— 卡牌 (10分)
      • 第4题 —— 最大数字 (10分)
      • 第5题 —— 出差 (15分)
      • 第6题 —— 费用报销 (15分)
      • 第7题 —— 故障 (20分)
      • 第8题 —— 机房 (20分)
      • 第9题 —— 齿轮 (25分)
      • 第10题 —— 搬砖 (25分)

补题链接:地址

在这里插入图片描述

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

第1题 —— 2022 (5分)

在这里插入图片描述

  • 题意:将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分)

在这里插入图片描述

  • 题意:这题题意表述不对,没说整点的时候,夹角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分)

在这里插入图片描述
在这里插入图片描述

  • 题意: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分)

在这里插入图片描述
在这里插入图片描述

  • 题意:给你一个数字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分)

在这里插入图片描述
在这里插入图片描述

  • 题意: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分)

在这里插入图片描述
在这里插入图片描述

  • 题意:给出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分)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 题意:给出一个矩阵,第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分)

在这里插入图片描述

在这里插入图片描述

  • 题意: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分)

在这里插入图片描述
在这里插入图片描述

  • 题意:给出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分)

在这里插入图片描述
在这里插入图片描述

  • 题意: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;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/519177.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

bbys_tu_2016

1,三连 思路&#xff1a;栈溢出 2&#xff0c;IDA分析 利用函数&#xff1a; 思路:ret2text 偏移&#xff1a;24 3&#xff0c;payload from pwn import * context.log_level"debug"rremote(node4.buuoj.cn,29195)flag 0x804856Dpayload 24 * a p32(flag) r.se…

Unittest单元测试框架之unittest构建测试套件

构建测试套件 在实际项目中&#xff0c;随着项目进度的开展&#xff0c;测试类会越来越多&#xff0c;可是直到现在我 们还只会一个一个的单独运行测试类&#xff0c;这在实际项目实践中肯定是不可行的&#xff0c;在 unittest中可以通过测试套件来解决该问题。 测试套件&…

七、Zookeeper注册中心

目录 1、下载Zookeeper的服务jar包 2、下载好jar包后解压放到合适的目录&#xff08;目录最好不要有中文及空格&#xff09; 3、进入解压后的conf目录&#xff0c;复制zoo_sample.cfg文件并重命名为zoo.cfg&#xff0c;修改zoo.cfg文件内容如下 4、运行bin目录下的zkServer…

split,paste,eval命令及正则表达式

一、split命令 将 linux 下的一个大文件拆分成若干小文件 1.语法格式 格式&#xff1a;split 选项 参数 原始文件 拆分后文件名前缀 常用选项: -l&#xff1a;以行数拆分 -b&#xff1a;以大小拆分 2.命令演示 2.1选项 -l &#xff1a;以行数分隔 cat -n anaconda-ks.cfg…

Windows系统安装好MongoDB后运行方法

文章目录 1、先找到安装MongoDB的文件位置的bin文件夹&#xff1a;2、找到data/db文件夹位置&#xff08;如果data文件夹中没有db文件夹需要创建一个&#xff09;&#xff1a;3、在刚刚打开的cmd窗口中运行以下命令&#xff1a;4、再另外从bin文件夹位置开一个cmd窗口&#xff…

图书管理系统(Java简单版)(完整代码+详解)

目录 详解&#xff1a; BookList类&#xff1a; InOperation接口 User类&#xff08;父类&#xff09; 和 Main类&#xff08;这俩要一起看&#xff09; 完整代码 book包 Book类 BookList类 operation包 AddBook类 BorrowBook类 DeleteBook类 FindBook类 Pr…

ESP32 FreeRTOS学习总结

2023.5.11 1.Task 创建任务常用API&#xff1a; 任务函数描述xTaskCreate()使用动态的方法创建一个任务xTaskCreatePinnedToCore指定任务的运行核心(最后一个参数)vTaskDelete(NULL)删除当前任务 BaseType_t xTaskCreate(TaskFunction_t pxTaskCode, // 任…

【HBase】架构

文章目录 整体架构Master负载均衡器元数据管理器预写日志处理器 Region ServerZookeeperHDFS Master架构Meta 表格 RegionServer 架构MemStoreWALBlockCache 读写流程HFile结构写流程读操作 整体架构 Master 实现类为 HMaster。 负责监控集群中所有的 RegionServer 实例。 &…

在Fedora-Workstation-Live-x86_64-36-1.5中使用佳能喷墨打印机ip2780

在Fedora-Workstation-Live-x86_64-36-1.5中使用佳能喷墨打印机ip2780 操作系统是64位的Fedora-Workstation-Live-x86_64-36-1.5.iso&#xff0c;实物打印机是佳能ip2780&#xff0c;USB接口 应用程序——其它——设置——打印机——解锁——输入root密码——将打印机USB插入电…

Redis数据结构——动态字符串、Dict、ZipList

一、Redis数据结构-动态字符串 我们都知道Redis中保存的Key是字符串&#xff0c;value往往是字符串或者字符串的集合。可见字符串是Redis中最常用的一种数据结构。 不过Redis没有直接使用C语言中的字符串&#xff0c;因为C语言字符串存在很多问题&#xff1a; 获取字符串长度…

智慧产业城彰显中国智造魅力,中联重科踏出“走上去”的关键一步

5月11日至14日&#xff0c;中联重科在长沙举行了“科技献礼新时代”系列活动。 借着活动&#xff0c;松果财经实地探访了全球规模最大、品种最全的工程机械产业基地&#xff0c;领略了前沿技术赋能先进制造的魅力。 作为湖南省“一号工程”和“十大重点项目之首”&#xff0c…

好家伙,又一份牛逼笔记面世了...

最近网传的一些裁员的消息&#xff0c;搞的人心惶惶。已经拿到大厂offer的码友来问我&#xff1a;大厂还能去&#xff0c;去了会不会被裁。 还在学习的网友来问我&#xff1a;现在还要冲互联网么&#xff1f; 我是认为大家不用恐慌吧&#xff0c;该看啥看啥&#xff0c;该学啥…

你一定要知道的unittest自动化测试框架详解

目录 框架的概念 Unittest单元测试框架 常用的assert语句 unittest创建测试代码的方式&#xff1a; unittest构建测试套件&#xff08;测试用例集合&#xff09;&#xff1a; unittest忽略测试用例&#xff1a; 运行测试集 批量执行测试用例 生成HTMLTestRunner测试报告…

【运维知识进阶篇】集群架构-Nginx基础(安装+启动+配置+多业务实现+日志管理)

本篇文章介绍下Nginx有关内容&#xff0c;Nginx是一个开源且高性能、可靠的Http Web服务、代理服务。 开源&#xff1a;直接获取源代码&#xff0c;高性能&#xff1a;支持海量并发&#xff0c;可靠&#xff1a;服务稳定 Web服务有很多&#xff0c;选择Nginx是因为他的轻量化…

【软件测试】测试开发的一生之敌-BUG

文章目录 1.前言2.如何描述/创建一个BUG3.BUG的级别4.BUG的生命周期5.跟开发产生争执怎么办 1.前言 BUG相比大家都知道,程序运行出错或者与预期不符就是BUG.现在我们来用测试人员的角度来看待BUG. 2.如何描述/创建一个BUG 测试人员要测试开发人员的代码,找出开发人员可能忽略…

敏态开发在大兴机场数字化转型中的实践

一、最大事业是育人 大兴机场是一个年轻的企业&#xff0c;作为一个企业来讲&#xff0c;最宝贵的就是人才。我们在2017年开始社招大学生&#xff0c;到目前为止&#xff0c;公司有一半都是30岁左右的年轻人&#xff0c;并且每年都会招几十个。年轻人特别想做事&#xff0c;而…

C++之内存管理及函数模版

C中的内存管理机制和C语言是一样的&#xff0c;但在具体内存管理函数上&#xff0c;C语言的malloc已经无法满足C面向对象销毁的需求&#xff0c;于是祖师爷在C中新增了一系列内存管理函数&#xff0c;即 new 和 delete 著名段子&#xff1a;如果你还没没有对象&#xff0c;那就…

( 位运算 ) 342. 4的幂 ——【Leetcode每日一题】

❓342. 4的幂 难度&#xff1a;简单 给定一个整数&#xff0c;写一个函数来判断它是否是 4 的幂次方。如果是&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 整数 n 是 4 的幂次方需满足&#xff1a;存在整数 x 使得 n 4 x n 4^x n4x。 示例 1&…

src学习记录(二)

学习目标&#xff1a; Apache Shiro ThinkPHP struts2 Apache Log4j Fastjson Weblogic 学习内容&#xff1a; 1.Apache Shiro 字段内容指纹信息请求包中&#xff0c;在Cookie信息中给 rememberMe变量赋任意值&#xff0c;收到返回包的Set-Cookie 值存在 rememberMedeleteMe …