传送门
题意:你有n种牌,第i种牌的数目为ci.另外有一种特殊的牌:joker,它的数目是m个.你可以用每种牌各一张来组成一套牌,也可以用一张joker和除了某一种牌以外的其他牌各一张组成1套牌.给出n,m和ci,你的任务是组成尽量多的套牌.每张牌最多只能用在一副套牌里(可以有牌不使用).
分析:如果这道题你不能看出可以二分答案求解,那...我们直接二分套牌数量mid,然后对于每种牌的数量ci,如果ci小于mid,那么就需要mid-ci张joker牌,如果当前mid下所需要的joker牌的数量小于等于m,说明此次mid合法.
想到这一步,应该都没问题.但还有一个坑,就是每一套牌只能有一张joker牌,所以我们上述最后一步判断合法性应该是:如果当前mid下所需要的joker牌的数量小于等于min(m,mid),说明此次mid合法.
int n,m,ans;
int c[55];
bool check(int mid){
int cnt=0,res=min(m,mid);//坑点
for(int i=1;i<=n;i++){
if(c[i]<mid){
cnt+=mid-c[i];
if(cnt>res)return 0;
}
else return 1;
//因为我在二分之前把c数组sort排序了一遍
//所以如果此次c[i]>mid,之后的c[i]就都大于mid了
//所以可以直接返回,节约时间
}
return 1;
}
int main(){
n=read();m=read();
for(int i=1;i<=n;i++)c[i]=read();
sort(c+1,c+n+1);
int l=0,r=c[n]+m,mid;//注意一下二分边界.
while(l<=r){
mid=(l+r)>>1;
if(check(mid)){
ans=mid;
l=mid+1;
}
else r=mid-1;
}
printf("%d\n",ans);
return 0;
}