欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

二分法应用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;
}