题解:Codeforces Round 961 (Div. 2) B1&B2
本题含有B1和B2两个难度版本。由于关系相近,我把他们放在同一篇博客中,可自行选择观看
B1. Bouquet (Easy Version)
time limit per test: 1.5 seconds
memory limit per test: 512 megabytes
input: standard input
output: standard output
This is the easy version of the problem. The only difference is that in this version, the flowers are specified by enumeration.
A girl is preparing for her birthday and wants to buy the most beautiful bouquet. There are a total of
这是问题的简单版本。唯一不同的是,在这个版本中,花朵是通过枚举来指定的。
一个女孩准备过生日,她想买一束最漂亮的花。商店里一共有
Input
Each test consists of several test cases. The first line contains a single integer
The first line of each test case contains two integers
The sum of
输入
每个测试由多个测试用例组成。第一行包含一个整数
每个测试用例的第一行包含两个整数
所有测试用例的
Output
For each test case, output a single integer — the maximum possible number of petals in the bouquet that the girl can assemble while meeting all the conditions listed above.
输出
对于每个测试用例,输出一个整数,即在满足上述所有条件的情况下,女孩在花束中可能组合的最大花瓣数。
Example
input
5 5 10 1 1 2 2 3 8 20 4 2 7 5 6 1 1 1 8 100000 239 30 610 122 24 40 8 2 11 13 2 4 11 1 1 2 3 5 4 3 2 8 1033 206 206 206 207 207 207 207 1000
output
7 13 610 13 1033
Note
In the first test case, you can assemble a bouquet with
注
在第一个测试用例中,可以用
题意
对每一个样例
题目会
- 给你一个n,代表有多少朵花
- 给你一个k,代表你需要有多少个花瓣(不能超过这个数)
- 给你n个数,代表有n朵花,每一个数代表这朵花有多少个花瓣
你有一个特点,你手中每朵花的花瓣数量只能有两种,且这两种花瓣数量相差不能超过1
求你能得到的最大的花瓣数量
我的题解
第一题是简单版本,给的数据量比较小
我们可以先排一下序,然后用 双指针算法 模拟 取值
当 后面的指针指向的值
比 前面的值加1
要大,就把前面的指针
不断往后挪
每次更新区间和
每次对区间和做一个判断
- 当区间和大于
时,就把前指针往后挪(减少区间和) - 否则,就把后指针往后挪(增大区间和)
每次循环都把区间和与答案作比较,取最大值更新答案
循环结束之后输出答案即可
我的代码
#include <bits/stdc++.h> #define int long long const int N = 2e5+10; int t,n,k; int num; int a[N]; void solve() { int ans = 0; int tem; std::cin >> n >> k; for(int i = 0 ; i < n ; i ++) std::cin >> a[i]; std::sort(a,a+n); int st = 0,en = 0; tem = a[0]; while(st <= en && en < n) { while(a[st] +1 < a[en]) { tem -= a[st]; st ++; } if(tem > k) { tem -= a[st]; st ++; } else { ans = std::max(ans,tem); en ++; tem += (en < n ? a[en] : 0); } } std::cout << ans << "\n"; } signed main() { std::cin >> t; while(t--) solve(); return 0; }
B2. Bouquet (Hard Version)
time limit per test: 1.5 seconds
memory limit per test: 256 megabytes
input: standard input
output: standard output
This is the hard version of the problem. The only difference is that in this version, instead of listing the number of petals for each flower, the number of petals and the quantity of flowers in the store is set for all types of flowers.
A girl is preparing for her birthday and wants to buy the most beautiful bouquet. There are a total of
**这是问题的困难版本。唯一不同的是,在这个版本中,不是列出每种花的花瓣数,而是为所有类型的花设定花瓣数和商店中的花的数量。
一个女孩准备过生日,想买一束最漂亮的花。店里一共有
Input
Each test consists of several test cases. The first line contains a single integer
The first line of each test case contains two integers
The sum of
输入
每个测试由多个测试用例组成。第一行包含一个整数
每个测试用例的第一行包含两个整数
所有测试用例中
Output
For each test case, print one integer — the maximum possible number of petals in a bouquet that a girl can collect, observing all the conditions listed above.
输出
对于每个测试用例,打印一个整数 - 在遵守上述所有条件的情况下,女孩在花束中可能收集到的最大花瓣数。
Example
input
7 3 10 1 2 3 2 2 1 3 1033 206 207 1000 3 4 1 6 20 4 2 7 5 6 1 1 2 1 3 1 7 8 100000 239 30 610 122 24 40 8 2 12 13123 112 1456 124 100 123 10982 6 13 2 4 11 1 3 5 2 2 1 2 2 1 8 10330 206 210 200 201 198 199 222 1000 9 10 11 12 13 14 15 16 2 10000000000 11 12 87312315 753297050
output
7 1033 19 99990 13 10000 9999999999
Note
In the first test case, some valid bouquets are
注
在第一个测试用例中,一些有效花束为
题意
对每一个样例
题目会
- 给你一个n,代表有多少种花
- 给你一个k,代表你需要有多少个花瓣(不能超过这个数)
- 给你n个数,代表有每一种花有多少个花瓣
- 给你n个数,代表相对应的每一种花有多少朵
你有一个特点,你手中每朵花的花瓣数量只能有两种,且这两种花瓣数量相差不能超过1
求你能得到的最大的花瓣数量
我的题解
这题是困难版本
我们可以用计数数组来模拟这个双指针算法的过程以节省内存空间
当然也可以用pair存储,我用的是map存储
我的做法是计数存储之后,
声明一个关于这个map的迭代器,反向遍历
假设迭代器迭代到取花瓣数
每次遍历都只取
每次计算,假设迭代器迭代到取花瓣数
先比较
- 如果小于等于
,那就全部取 - 如果比
大- 假设全部取
,会有两种情况- 全部取
之后手上的花瓣数不超过 ,那就再从 那里拿一些花瓣(假设取 朵,使得手上的花瓣数最大且不超过 ) - 全部取
之后手上的花瓣数超过 ,那就放回部分 ,使得手上的花瓣数不大于
- 全部取
- 然后,我们计算最多能把多少朵手上的a换成b(因为每换一朵花瓣数就加
),这个数量
也就是 - 再把手上的花瓣数加上
,和目前的结果比较,取最大值更新结果
- 假设全部取
输出最后的结果即可
同样的逻辑套用在B1也可以通过
我的代码
#include <bits/stdc++.h> #define int long long const int N = 2e5+10; int t,n,k; int num; int a[N]; int fin(std::map<int,int> &mp,std::map<int,int>::iterator &poi) { int bi = poi->first+1; int teme = poi->second * poi->first + mp[bi] * bi; int ans_t; if(teme > k) { ans_t = std::min(k/poi->first,poi->second) * poi->first; int add_m = std::min((k-ans_t)/bi,mp[bi]); ans_t += add_m*bi; int add_t = std::min(std::min(k/poi->first,poi->second),mp[bi]-add_m); ans_t += std::min(k-ans_t,add_t); ans_t = std::max(ans_t,std::min(k/bi , mp[bi]) * bi); return ans_t; } else { return teme; } } void solve() { int ans = 0; std::cin >> n >> k; std::map<int,int> mp; for(int i = 0 ; i < n ; i ++) { std::cin >> a[i]; } for(int i = 0 ; i < n ;i ++) { std::cin >> mp[a[i]]; } std::map<int,int>::iterator poi = mp.end(); poi --; while(poi != mp.begin() && ans < k) { ans = std::max(ans,fin(mp,poi)); poi --; } ans = std::max(ans,fin(mp,poi)); std::cout << ans << "\n"; } signed main() { std::ios::sync_with_stdio(false); std::cin.tie(nullptr); std::cout.tie(nullptr); std::cin >> t; while(t--) solve(); return 0; }
posted on 2024-07-25 16:49 Jiejiejiang 阅读(44) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现