牛客—— [CQOI2010]扑克牌 (二分)
原题链接:https://ac.nowcoder.com/acm/problem/19916
##题意:
给n种牌,每种牌c[i]个,和m张万能牌,问最多能够组成多少套牌(包含所有的种类)
思路:
考虑二分答案,贪心进行检验。
如果最多能够构成x套牌,每种牌至少x张,如果c[i]<x的话就要用万能牌去补齐。
在check的时候,当c[i]<x时才使用万能牌,当万能牌不够时说明该答案偏大。
代码:
#pragma GCC optimize(2) #include<bits/stdc++.h> using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int,int>PII; #define I_int ll inline ll read() { ll x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } char F[200]; inline void out(I_int x) { if (x == 0) return (void) (putchar('0')); I_int tmp = x > 0 ? x : -x; if (x < 0) putchar('-'); int cnt = 0; while (tmp > 0) { F[cnt++] = tmp % 10 + '0'; tmp /= 10; } while (cnt > 0) putchar(F[--cnt]); cout<<endl; } const int maxn=1e6+10; ll n,m; ll c[maxn]; bool check(ll mid){ ll tmp=min(mid,m); for(int i=1;i<=n;i++){ tmp-=max(mid-c[i],0ll); if(tmp<0) return 0; } return 1; } int main(){ n=read(),m=read(); for(int i=1;i<=n;i++) c[i]=read(); ll l=1,r=1e9,res; while(l<=r){ ll mid=(l+r)/2; if(check(mid)) res=mid,l=mid+1; else r=mid-1; } out(res); return 0; }