牛客 [CQOI2010]扑克牌 ###K ###K //K
题目链接:https://ac.nowcoder.com/acm/problem/19916
刚开始想的是贪心 把joker 和最大的n-1个在一起减了
在和最小的那个 再取一次最小 这样贪心是错的 如3 10 2 2 2 贪心只能取2套 但最多可以组3套
思路:因为 满足x套 那么 少于x套的肯定也能组成 有单调性 所以考虑二分
主要就是如何check 不从每一套里面单独考虑 而是整体考虑 假设 当前check到mid套 那么此时需要的牌为sum=mid*n张
如果c[i]>mid 的 那么就给mid张 即sum-=mid 因为每套至多给一张同样的 如果c[i]<=mid 的 那么就全部都可以拿来用
最后比较 sum和 m的大小以及和mid的大小 如果sum>mid 那么肯定不满足 因为joker最多给mid张
如果sum<=mid 那么再比较sum和m 然后记得开ll QAQ
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define pb push_back 5 const int maxn =2e5+10; 6 const int mod=1e9+7; 7 ll c[55]; 8 int n,m; 9 int check(ll x) 10 { 11 ll sum=x*n; 12 for(int i=1;i<=n;i++) 13 { 14 if(c[i]>=x) 15 { 16 sum-=x; 17 } 18 else 19 { 20 sum-=c[i]; 21 } 22 } 23 if(sum>x||sum>m) 24 { 25 return 0; 26 } 27 else 28 return 1; 29 } 30 int main() 31 { 32 ios::sync_with_stdio(false); 33 cin.tie(0); 34 cin>>n>>m; 35 for(int i=1;i<=n;i++) 36 { 37 cin>>c[i]; 38 } 39 ll l=0,r=1e9; 40 ll ans=0; 41 while(l<=r) 42 { 43 ll mid=(l+r)/2; 44 if(check(mid)) 45 { 46 ans=mid; 47 l=mid+1; 48 } 49 else 50 r=mid-1; 51 } 52 cout<<ans<<'\n'; 53 54 55 56 57 }

浙公网安备 33010602011771号