二分法应用NUSOJ 3053集N“福”
程序员文章站
2024-03-16 23:09:40
...
写了那么多简单的二分法,这次来一个需要思考的二分法吧,强大的二分法!!!!
Description:
众所周知!支付宝每年都会推出线上集五“福”活动来吸引流量,有着传统祖训的腾讯怎么会坐视不管!本着“你可能小赚,但我永远不亏”的原则推出了线上集N“福”活动。zzl学长作为腾讯的忠实粉丝早就关注活动很久了。
已知:zzl学长有n种“福”卡,第i种福卡的数目为ai,并且有m张万能福(万能福可以代替任意一种福卡),zzl学长可以用n种福卡各一张来合成一个抽奖碎片,合成过程中可以使用万能福,但是每次合成最多使用一张万能福,问zzl学长最多可以合成多少个抽奖碎片。
Input:
多组输入
第一行包含两个整数n, m,即“福”的种数和万能福的张数。(2< = n < = 50, 0 < = m<= 500,000,000)
第二行包含n个整数ai,即每种“福”的张数。(0 < = ai <= 500,000,000)
Output:
输出仅一个整数,即最多能合成抽奖碎片的数量
Sample Input
3 10
2 2 10
3 4
1 2 3
3 0
1 2 3
Sample Output
4
3
1
#include<bits/stdc++.h>
using namespace std;
int n,m;
int binary(int mid,int a[]){
int mm = min(mid,m);
for(int i=0;i<n;i++){
if(mid > a[i]) mm = mm-(mid-a[i]);//得到如果mid套需要的万能福数量
if(mm<0) return 0;
}
return 1;
}
int main()
{
while(~scanf("%d%d",&n,&m)){
int a[111];
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
int ans;
int left = 0, mid ,right = 1e9;
while(left<=right){
mid = left + ((right-left)>>1);
if(binary(mid,a)==0){
right = mid-1;//若无减一无法left<=right
}
else {
left = mid+1;//若无加一无法left<=right
ans = mid;
}
}
cout<<ans<<endl;
}
return 0;
}