第十三届蓝桥杯B组c++国赛

A - 2022:

题目:

笔记:

一道经典的dp题:

(1)明确dp数组含义:

dp[i][j][k]: 表示前i个数字中选择j个凑成k的方法数。

(2)确定状态转移方程:

dp[i][j][k] = dp[i - 1][j - 1][k - i] + dp[i - 1][j][k]

有两种情况,如果当前遍历到的数字i大于背包容量则肯定不取,如果小于则可以取。

(3)初始化:

由于后续的所有方法数都是依赖于底层组成0的方法数:

所以将第一层容量为0的背包都设置为1。

(4)遍历顺序:

就是从小到大遍历即可,并未涉及状态压缩:

#include<bits/stdc++.h>
using namespace std;int main(){long long dp[2023][11][2023] = {0};for(int i = 0; i < 2023; i++){dp[i][0][0] = 1;}for(int i = 1; i < 2023; i++){for(int j = 1; j <= 10; j++){for(int k = 1; k < 2023; k++){if(i <= k){dp[i][j][k] = dp[i - 1][j - 1][k - i] + dp[i - 1][j][k];}else{dp[i][j][k] = dp[i - 1][j][k];}}}}cout << dp[2022][10][2022] << endl;return 0;
}

 B - 钟表:

题目:

笔记:

简单模拟题:

#include <bits/stdc++.h>
using namespace std;
int main()
{// 时针:// 360 / 12 = 30°// 30 / 60 = 0.5°// 0.5 / 60 = 1/120°// 分针:// 360 / 60 = 6°// 6 / 60 = 0.1°// 秒针:// 360 / 60 = 6°for(int i = 0; i <= 6; i++){for(int j = 0; j < 60; j++){for(int k = 0; k < 60; k++){double h = i * 30.0 + j / 2.0 + k / 120.0; // 6点附近double m = j * 6.0 + k / 10;double s = k * 6.0;double a = abs(m - h);double b = abs(s - m);if(a > 180){a = 360 - a;}if(b > 180){b = 360 - b;}if(a == 2 * b){if(i == 0 && j == 0 && k == 0){continue;}cout << i << " " << j << " " << k;}}}}return 0;
}

C - 0卡牌:

题目:

笔记:

这道题目有点贪心的意思:

我们的思路是优先将已有牌中数目最少的牌补齐:所以我们需要有一个数组来存储已有牌的数目以及对应最多能够补几张:然后我们对该数组进行排序,优先补齐数量最少的牌查看是否能够凑齐指定套数的牌:

D - 最大数字:

题目:

笔记:

为了更好地处理,我们先将数字转换成字符串类型进行处理:

明确我们的目的:将数字改的尽可能的大,我们的限制条件是:opt_1操作次数不能超过A次,opt_2操作不能超过B次:我们可以先判断opt_2的数量是否大于当前数字cur + 1,如果不大于就只选择opt_1不再进行opt_2操作,如果当opt_2的数量大于cur + 1, 那么就优先将opt_2的数量消耗掉,因为opt_2只能通过正好将cur变成9才会变大,而opt_1无论怎样都会使数字变大。

#include <iostream>
#include <sstream>
using namespace std;
typedef long long ll;int main() {ll n, a, b;cin >> n >> a >> b;stringstream ss;ss << n;string str = ss.str();for (ll i = 0; i < str.size(); i++) {ll digit = str[i] - '0'; // 将字符转换为整数if (b >= digit + 1) {b -= (digit + 1);str[i] = '9';} else {if (a <= 0) break;ll need = 9 - digit;if (need <= a) {str[i] = '9';a -= need;} else {str[i] = digit + a + '0'; // 将整数转换回字符a = 0;break;}}}// 使用 stringstream 将字符串转换为整数ll result;stringstream(str) >> result;cout << result << endl;return 0;
}

但是这么写只过90%,

E - 出差:

这道题就是一个迪杰斯特拉的模板题,让我们找到一条从城市1出发到达城市n的最短路径,

#include<iostream>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
#define int long long
typedef pair<int,int>PII;
const int N=1e5+5,M=2*N;
int h[N],e[M],ne[M],w[M],a[N],dist[N],vis[N],idx;
void add(int x,int y,int z){e[idx]=y,w[idx]=z,ne[idx]=h[x],h[x]=idx++;//数组e是代表当前边的终点//数组w是代表当前边的权重//数组ne表示next的指针是只想同一起点的边的下标
}
void dijkstra(){memset(dist,0x3f,sizeof dist);priority_queue<PII,vector<PII>,greater<PII> >q;q.push({0,1});dist[1]=0;while(q.size()){int dis=q.top().first;int s=q.top().second;q.pop();if(vis[s])continue;vis[s]=1;for(int i=h[s];~i;i=ne[i]){int j=e[i];if(dist[j]>dis+w[i]){dist[j]=dis+w[i];q.push({dist[j],j});}}}
}
signed main(){memset(h,-1,sizeof h);int n,m;cin>>n>>m;for(int i=1;i<=n;i++)cin>>a[i];while(m--){int x,y,z;cin>>x>>y>>z;add(x,y,z+a[y]);add(y,x,z+a[x]); }dijkstra();cout<<dist[n]-a[n]<<endl;return 0;
}
#include<bits/stdc++.h>
using namespace std;int main(){int n, m;cin >> n >> m;vector<int> t(n + 1, 0);for(int i = 1; i <= n; i++){cin >> t[i];}// 存图:vector<vector<int>> grid(n + 1, vector(n + 1, INT_MAX));for(int i = 1; i <= m; i++){int start, end, cost;cin >> start >> end >> cost;grid[start][end] = cost + t[end];grid[end][start] = cost + t[start];}priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> que;vector<bool> visited(n + 1, false);que.push(make_pair(0, 1));vector<int> mindist(n + 1, INT_MAX);mindist[1] = 0;while(!que.empty()){pair<int, int> cur = que.top(); que.pop();int end = cur.first;int start = cur.second;if(visited[start])  continue;visited[start] = true;for(int i = 1; i <= n; i++){if(!visited[i] && grid[start][i] != INT_MAX && mindist[start] + grid[start][i] < mindist[i]){mindist[i] = grid[start][i] + mindist[start];que.push(make_pair(mindist[i], i));}}}if(mindist[n] == INT_MAX){cout << -1;}else{cout << mindist[n] - t[n];}return 0;
}

注意优先队列中元素排列的顺序。

F - 费用报销:

题目:

笔记:

#include <bits/stdc++.h>
using namespace std;const int N = 1010;
int f[N][N * 5];
int s[N], last[N];
int d[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};//每个月份的天数
int n, m, k;
struct Node
{int m, d, v, t;
} p[N];// 定义一个日期结构体:包含月份,天数,价值,相对年初的天数bool cmp(Node &a, Node &b)
{return a.t < b.t;
}int main()
{scanf("%d%d%d", &n, &m, &k);for (int i = 2; i <= 12; i++) s[i] = s[i - 1] + d[i - 1];// 前缀和计算当前月相对年初的天数// 为每一个日期结构体的t日期进行赋值:for (int i = 1; i <= n; i++){scanf("%d%d%d", &p[i].m, &p[i].d, &p[i].v);p[i].t = s[p[i].m] + p[i].d;}// 按日期结构的天数进行升序排列sort(p + 1, p + 1 + n, cmp);// 找出距离当前项目最近的可以选择的项目的编号,因为当你遍历到一个日期需要查看预支配对的上一个可行的日期。for (int i = 1; i <= n; i++)for (int j = 0; j < i; j++)if (p[i].t - p[j].t >= k)last[i] = j;for (int i = 1; i <= n; i++)for (int j = 0; j <= m; j++){    f[i][j] = f[i - 1][j]; // 不选第i个,状态则为i-1if (p[i].v <= j && (p[i].t - p[i - 1].t) >= k)  // 如果选第i个,则要看背包是否装得下才比较f[i][j] = max(f[i][j], f[i - 1][j - p[i].v] + p[i].v);}cout << f[n][m];return 0;
}

耗费大量精力也是终于复刻出来了:

这道题归根到底就是一道01背包的题目,但是我们需要注意的是在我们对当前物品取与不取的选择中,如果我们选择取那么记忆化搜索调用上一个物品的最大金额dp[i - 1][j - v],这里并不仅仅是上一个物品,因为我们的限制条件是天数要大于等于k,所以上一个日期可能并没有达到k,可能需要用到上上个日期或者上上上个日期,所以我们就需要注意到底是取哪一个日期作为i- 1,这里我们用到了一个last数组记录每一个日期对应的上一个可选择日期,我们利用一个快慢指针搜索距离当前日期最近的可选日期。然后就可以按正常的逻辑进行dp:

dp[i][j] = max(dp[i - 1][j], dp[last[i]][j - value] + value):

#include<bits/stdc++.h>
using namespace std;
struct date_m{int m, d, v, t;// t表示当前日期与年初的天数
};
// 用于结构体排序,将日期按距离年初的天数从小到大排序
bool com(date_m& a, date_m& b){return a.t < b.t;
}
// 每个月的日期,用来计算当前日期距年初的天数
int mon[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int sum(int x){int a = 0;for(int i = 1; i < x; i++){a += mon[i];}return a;
}int main(){int n, m, k;cin >> n >> m >> k;vector<date_m> date(n + 1);for(int i = 1; i <= n; i++){cin >> date[i].m >> date[i].d >> date[i].v;date[i].t = sum(date[i].m) + date[i].d;}sort(date.begin(), date.end(), com);//cout << date[4].t << endl;vector<int> last(n + 1, 0);for(int i = 2; i <= n; i++){for(int j = 1; j < i; j++){if((date[i].t - date[j].t) >= k){last[i] = j;}}}vector<vector<int> > dp(n + 1, vector<int>(m + 1, 0));for(int i = 1; i <= n; i++){for(int j = 0;j <= m; j++){dp[i][j] = dp[i - 1][j];if(j >= date[i].v){dp[i][j] = max(dp[i - 1][j], dp[last[i]][j - date[i].v] + date[i].v);}}}cout << dp[n][m] << endl;return 0;
}

H - 机房:

题目:

笔记:

就是迪杰斯特拉的模板题:

#include<bits/stdc++.h>
using namespace std;
const int Max = 1e5 + 5;int main(){int n, m;cin >> n >> m;vector<int> edge[Max];// 读取 m 条边for(int i = 0 ; i < n - 1; i++){int a, b;cin >> a >> b;edge[a].push_back(b);edge[b].push_back(a);}vector<int> res(m, 0);for(int i = 0; i < m; i++){int u, v;cin >> u >> v;priority_queue<pair<int, int>, vector<pair<int, int> >, greater<pair<int, int> > > que;vector<int> mindist(n + 1, INT_MAX); // 使用 INT_MAX 初始化mindist[u] = 0;vector<bool> vis(n + 1, false);que.push(make_pair(0, u));while(!que.empty()){pair<int, int> cur = que.top(); que.pop();int cost = cur.first;int start = cur.second;if(vis[start])  continue;vis[start] = true;int len = edge[start].size();for(int j = 0; j < len; j++){int dot = edge[start][j];if( mindist[dot] > mindist[start] + len){mindist[dot] = mindist[start] + len;que.push(make_pair(mindist[dot], dot)); // 更新优先队列}}}// 检查是否存在路径if(mindist[v] != INT_MAX) {res[i] = mindist[v] + edge[v].size();} else {res[i] = -1; // 如果不存在路径,输出 -1}}for(int i = 0; i < m; i++){cout << res[i] << endl;}return 0;
}
#include<bits/stdc++.h>
using namespace std;
const int Max = 1e5 + 5;int main(){int n, m;cin >> n >> m;vector<int> edge[Max];// 读取 m 条边for(int i = 0 ; i < n - 1; i++){int a, b;cin >> a >> b;edge[a].push_back(b);edge[b].push_back(a);}vector<int> res(m, 0);for(int i = 0; i < m; i++){int u, v;cin >> u >> v;priority_queue<pair<int, int>, vector<pair<int, int> >, greater<pair<int, int> > > que;vector<int> mindist(n + 1, INT_MAX); // 使用 INT_MAX 初始化mindist[u] = 0;vector<bool> vis(n + 1, false);que.push(make_pair(0, u));while(!que.empty()){pair<int, int> cur = que.top(); que.pop();int cost = cur.first;int start = cur.second;if(vis[start])  continue;vis[start] = true;int len = edge[start].size();for(int j = 0; j < len; j++){int dot = edge[start][j];if(!vis[dot] && mindist[dot] > mindist[start] + len){mindist[dot] = mindist[start] + len;que.push(make_pair(mindist[dot], dot)); // 更新优先队列}}}// 检查是否存在路径if(mindist[v] != INT_MAX) {res[i] = mindist[v] + edge[v].size();} else {res[i] = -1; // 如果不存在路径,输出 -1}}for(int i = 0; i < m; i++){cout << res[i] << endl;}return 0;
}

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

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

相关文章

C++中的引用和解引用,及在Lambda中的简单使用

目录 摘要 引用&#xff08;Reference&#xff09; 定义 用法 解引用&#xff08;Dereference&#xff09; 定义 用法 Lambda表达式结合引用和解引用 引用结合Lambda表达式 解引用结合Lambda表达式 较为复杂的使用 总结 摘要 在C中&#xff0c;引用&#xff08;Re…

linux 内核哪种锁可以递归调用 ?

当数据被多线程并发访问(读/写)时&#xff0c;需要对数据加锁。linux 内核中常用的锁有两类&#xff1a;自旋锁和互斥体。在使用锁的时候&#xff0c;最常见的 bug 是死锁问题&#xff0c;死锁问题很多时候比较难定位&#xff0c;并且影响较大。本文先会介绍两种引起死锁的原因…

Java-----String类

1.String类的重要性 经过了C语言的学习&#xff0c;我们认识了字符串&#xff0c;但在C语言中&#xff0c;我们表示字符串进行操作的话需要通过字符指针或者字符数组&#xff0c;可以使用标准库中提供的一系列方法对字符串的内容进行操作&#xff0c;但这种表达和操作数据的方…

沟通程序化(1):跟着鬼谷子学沟通—“飞箝”之术

沟通的基础需要倾听&#xff0c;但如果对方听不进你的话&#xff0c;即便你说的再有道理&#xff0c;对方也很难入心。让我们看看鬼谷子的“飞箝”之术能给我们带来什么样的启发吧&#xff01; “飞箝”之术&#xff0c;源自中国古代兵法家、纵横家鼻祖鬼谷子的智慧&#xff0…

SpringBootWeb 篇-深入了解 Spring 异常处理、事务管理和配置文件参数配置化、yml 配置文件

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 配置文件 1.1 yml 配置文件 1.2 参数配置化 1.2.1 使用 Value 注解注入单个配置参数 1.2.2 使用 ConfigurationProperties 注解将一组相关配置参数注入到一个类中…

discuz论坛怎么修改备案信息

大家好&#xff0c;今天给大家分享下discuz如何填写备案信息并且展示在网站首页。大家都知道国内网站都需要备案&#xff0c;不通过备案的网站上是没办法通过域名打开的。大家也可以通过搜索网创有方&#xff0c;或者直接点击网创有方 查看悬挂备案号后的效果。 首先大家可以看…

如何在CentOS中合理划分磁盘空间以优化系统性能

目录 前言 理想的分区方案 为什么需要单独分区 安全性 性能 管理和维护 稳定性和可靠性 升级和兼容性 结论 前言 在进行CentOS系统的安装和配置时&#xff0c;合理划分磁盘空间是确保系统性能、安全性和易于管理的关键步骤。本文将探讨如何根据系统的硬件配置和预期用途…

安全测试扫描利器-Burpsuite

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

vscode常用插件及插件安装方式

一、常用插件 Chinese (Simplified) (简体中文) Language Pack for Visual Studio Code 说明&#xff1a;中文语言包扩展&#xff08;简体&#xff09; open in browser 说明&#xff1a;可以在默认浏览器或应用程序中打开当前文件 Auto Rename Tag 说明&#xff1a;自动重…

Linux 命令:awk

1. 写在前面 本文主要介绍 Linux “awk” 命令&#xff1a;“awk” 是另一个强大的文本处理工具&#xff0c;用于处理和操作结构化数据&#xff0c;如日志文件和命令输出。它可以根据需要为我们打印特定的列值。 公众号&#xff1a; 滑翔的纸飞机 2. awk 命令 我们能用 awk 做…

Android 控件保持宽高比得几种方式

文章目录 Android 控件保持宽高比得几种方式adjustViewBounds百分比布局ConstraintLayout自定义View Android 控件保持宽高比得几种方式 adjustViewBounds 仅适用于 ImageView&#xff0c;保持横竖比。 <ImageViewandroid:layout_width"match_parent"android:l…

动态规划(Dynamic-Programming)问题讲解

动态规划类问题 从已知子问题的解&#xff0c;推导出当前问题的解 推导过程可以表达为一个数学公式用一维或二维数组来保存之前的计算结果&#xff08;可以进一步降维优化&#xff09; 将当前问题 分解成子问题 &#xff0c;找出递归公式&#xff0c;分阶段进行求解 求解过程中…

vue3+ts封装一个button组件

创建一个新的Button组件文件 Button.vue&#xff1a; <template><button :class"buttonClass" :disabled"disabled" click"handleClick"><slot></slot><i v-if"icon" :class"icon"></i&g…

python 生成器yield

生成器 创建生成器的方式 生成器推导式yield关键字 生成器相关方法 for&#xff1a;循环遍历生成器中的每一个值next&#xff1a;获取生成器中的下一个值 生成器注意点 代码执行到yield会暂停&#xff0c;然后把结果返回出去&#xff0c;下次启动生成器会在暂停的位置继续执行…

进程间通信(27000字超详解)

&#x1f30e;进程间通信 文章目录&#xff1a; 进程间通信 进程间通信简介       进程间通信目的       初识进程间通信       进程间通信的分类 匿名管道通信       认识管道       匿名管道       匿名管道测试       管道的四种…

第十五课,海龟画图:抬笔与落笔函数、画曲线函数

一&#xff0c;turtle.penup()和turtle.pendown()&#xff1a;抬起与落下画笔函数 当使用上节课学习的这个turtle.forward()&#xff1a;画笔前进函数时&#xff0c;画笔会朝着当前方向在画布上留下一条指定&#xff08;像素&#xff09;长度的直线&#xff0c;但你可能发现&a…

Map Python用法:深度解析与应用探索

Map Python用法&#xff1a;深度解析与应用探索 在Python编程中&#xff0c;map() 函数是一种强大的内置高阶函数&#xff0c;用于对可迭代对象中的每个元素应用指定的函数&#xff0c;并返回一个新的迭代器&#xff0c;其中包含函数应用后的结果。本文将从四个方面、五个方面…

Bean的生命周期中有哪些对外开放的接口,及各种作用

Bean的生命周期中有哪些对外开放的接口&#xff0c;及各种作用 在 Spring 框架中&#xff0c;Bean 的生命周期可以通过一系列的回调接口来管理和控制。以下是 Spring 中对外开放的主要 Bean 生命周期接口以及它们的作用&#xff1a; InitializingBean 和 DisposableBean 接口&…

C++|set、map模拟实现<——红黑树

目录 一、红黑树的迭代器 1.1红黑树迭代器框架 1.2operator*() && operator->() 1.3operator() 1.4operator--() 1.5operator() && operator!() 1.6begin() && end() 二、如何用红黑树搭配map和set(仿函数) 三、红黑树封装map和set(简易版…

springboot + Vue前后端项目(第十三记)

项目实战第十三记 写在前面1.建立角色表2. 后端代码生成2.1 RoleController 3. 前端页面的搭建3.1 Role.vue3.2 路由3.3 Aside.vue3.4 页面效果 4.建立菜单表5.后端代码编写5.1 Menu5.2 MenuController 6.前端页面的搭建6.1 Menu.vue6.2 路由6.3 Aside.vue6.4 页面效果 总结写在…