P8800 [蓝桥杯 2022 国 B] 卡牌
分析
“最多” -- 二分
1.二分区间(凑齐的卡牌套数):
l:a[]min;r:(a[]+b[])max
2.check(x):
(1)for循环内:
判断x - a[i] <= b[i](对于 i 种牌,假设把空白牌用完,是否能凑齐x套)
Y:定义一个变量,加上x - a[i](对于第 i 种牌,凑齐x套需要的空白牌数)
N:return false;
(2)判断需要的空白牌是否超出题目给的范围(if(s <= m))
s <= m:
s == m:ans = mid
s < m:l = mid + 1
s > m:
r = mid - 1
代码
注意:一定一定一定记得开long long.....
scanf("%lld")!!!
#include<iostream>
using namespace std;
typedef long long ll;
const int N = 200010;
int a[N],b[N],n;
ll m;
bool check(int x)
{
ll s = 0;
for(int i = 0;i < n;i ++)
{
if(x - a[i] <= b[i])
{
if(x - a[i] > 0)
s += (x - a[i]);
}
else return false;
}
if(s <= m) return true;
else return false;
}
int main()
{
int l = 0x3f3f3f3f,r = 0;
scanf("%d %lld",&n,&m);
for(int i = 0;i < n;i ++)
{
scanf("%d",&a[i]);
l = min(l,a[i]);
}
for(int i = 0;i < n;i ++)
{
scanf("%d",&b[i]);
r = max(r,a[i] + b[i]);
}
int ans = 0;
while(l <= r)
{
int mid = l + r >> 1;
if(check(mid))
{
ans = mid;
l = mid + 1;
}
else r = mid - 1;
}
printf("%d",ans);
return 0;
}