C++:蓝桥杯-22真题-卡牌
单纯进行记录,熟悉一下思路
文章目录
题目
这天,小明在整理他的卡牌。
他一共有 n 种卡牌,第 i 种卡牌上印有正整数数 i(i ∈ [1, n]),且第 i 种卡牌 现有 ai 张。
而如果有 n 张卡牌,其中每种卡牌各一张,那么这 n 张卡牌可以被称为一 套牌。小明为了凑出尽可能多套牌,拿出了 m 张空白牌,他可以在上面写上数 i,将其当做第 i 种牌来凑出套牌。然而小明觉得手写的牌不太美观,决定第 i 种牌最多手写 bi 张。
请问小明最多能凑出多少套牌?
一、思路
//二分法思路
1.取一个中间值作为a的中位数,mid
2.变量所有a[],对a中小于mid的所有值都进行添加,sum累加,同时判断sum是否大于空牌总数m,
同时判断需要手写补的牌是否大于b[]
3.用l和r来控制mid值,当a中都符合mid值添加时,右移即l=mid+1;当a中有不符合mid值添加条件的,左移r=mid-1;
4.当a都符合mid值添加时,即ans = mid
二、代码
/*
22年蓝桥杯决B组赛真题-卡牌
//二分法思路
1.取一个中间值作为a的中位数,mid
2.变量所有a[],对a中小于mid的所有值都进行添加,sum累加,同时判断sum是否大于空牌总数m,
同时判断需要手写补的牌是否大于b[]
3.用l和r来控制mid值,当a中都符合mid值添加时,右移即l=mid+1;当a中有不符合mid值添加条件的,左移r=mid-1;
4.当a都符合mid值添加时,即ans = mid
*/
#include "iostream"
#include "vector"
#include "map"
#include "bits/stdc++.h" //包含了所有c++文件,刷题可用,做项目不用
using namespace std;
long long a[1000005], b[1000005];
// vector<int> a, b;
//判断a遍历mid是否符合条件
bool check(int mid, int n, int m)
{
long long sum = 0;
for (int i = 0; i < n; i++)
{
if (a[i] < mid)
{
if (mid - a[i] > b[i])
{
return false;
}
sum += mid - a[i];
if (sum > m)
{
return false;
}
}
}
return true;
}
int main(int argc, const char **argv)
{
long long n, m;
cin >> n >> m;
for (int i = 0; i < n; i++)
{
// int tempA;
// cin >> tempA;
// a.push_back(tempA);
cin >> a[i];
}
for (int i = 0; i < n; i++)
{
// int tempB;
// cin >> tempB;
// b.push_back(tempB);
cin >> b[i];
}
long long l = 0, r = n, ans = 0;
while (l <= r)
{
long long mid = (l + r) / 2;
if (check(mid, n, m))
{
l = mid + 1;
ans = mid;
}
else
{
r = mid - 1;
}
}
cout << ans << endl;
return 0;
}
总结
这段代码通过96分,应该是long long长度问题没有100分,但也不确定,思路基本掌握
使用vector 的话,通过92分
参考
https://blog.csdn.net/m0_58177653/article/details/125345906?ops_request_misc=&request_id=&biz_id=102&utm_term=%E8%93%9D%E6%A1%A5%E6%9D%AF%E5%8D%A1%E7%89%8C&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduweb~default-8-125345906.142v73wechat,201v4add_ask,239v2insert_chatgpt&spm=1018.2226.3001.4187#t3