题目如上,问最多可以凑出几副牌,由于这题有二分的性质,所以可以用二分解决这个问题
步骤如下:
- 计算a[i]+b[i]的最小值minn,计算a[1]+a[2]+...+a[n]+m的值sum,所以二分的右边界可以是min(minn,sum/n)
- 开始二分,用mid存储(l+r)/2,如果m个卡牌不能让已有的牌成为mid副牌,则返回false,否则返回true
- 最后输出l或r都可
C++代码如下:
#include<iostream>
using namespace std;
const int N=200010;
typedef long long LL;//数据较大,防止爆int
int a[N],b[N];
LL n,m,sum,ans;
bool check(int mid){//判断能否组成mid副牌
LL res=0;
for(int i=1;i<=n;i++){
if(a[i]<mid)
res+=mid-a[i];
}
return res<=m;//若res<=m,则表示可以
}
int main(){
cin>>n>>m;
int minn=1e9;
for(int i=1;i<=n;i++)cin>>a[i],sum+=a[i];
sum+=m;
for(int j=1;j<=n;j++)cin>>b[j],minn=min(a[j]+b[j],minn);
int l=0,r=min(sum/n,(LL)minn);
while(l<r){
int mid=l+r+1>>1;
if(check(mid))l=mid;
else r=mid-1;
}
cout<<l<<endl;
return 0;
}