扑克牌
题意:给你n种牌,并给你这n种牌的张数,再给你m张万能牌,让你求最多配出多少套牌(就是n中 种牌,一种一张)
题解:知识点:二分
从整体上来看,配出的多少套牌是单调的,想到二分。
重点说一下check判断函数吧,因为你二分出来结果是,一定要判断结果是否符合,如果你配x套,需要大于m张万能牌,那么这样肯定是不行的,再者一套牌中有两张万能牌也是不符合题意的,所以生成了这两个判断条件。
注意一下:他的右端不要设5e8,我当时就看到他给的范围是5e8我就设的5e8,这样想一下,如果n种牌都有5e8,再有5e8个万能牌,会怎样?当然结果就不在5e8范围内了。所以最右端应该是2*5e8。因为一套牌最多有一个万能牌,所以配出来的,最多加上n种牌数量最多的那个个数。也就是5e8+5e8喽。
代码:
#include <map> #include <queue> #include <string> #include<iostream> #include<stdio.h> #include<string.h> #include <algorithm> #include <math.h> typedef long long ll; typedef unsigned long long ull; using namespace std; typedef pair<ll,ll> pii; #define mem(a,x) memset(a,x,sizeof(a)) #define debug(x) cout << #x << ": " << x << endl; #define rep(i,n) for(int i=0;i<(n);++i) #define repi(i,a,b) for(int i=int(a);i<=(b);++i) #define repr(i,b,a) for(int i=int(b);i>=(a);--i) const int maxn=2e5+1010; #define inf 0x3f3f3f3f #define sf scanf #define pf printf const int mod=998244353; const int MOD=10007; inline int read() { int x=0; bool t=false; char ch=getchar(); while((ch<'0'||ch>'9')&&ch!='-')ch=getchar(); if(ch=='-')t=true,ch=getchar(); while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar(); return t?-x:x; } /*priority_queue<ll , vector<ll> , greater<ll> > mn;//上 小根堆 小到大 priority_queue<ll , vector<ll> , less<ll> > mx;//下 大根堆 大到小 map<ll,ll>mp;*/ ll n,m,t,l,r,p; ll sum,ans,res,cnt,flag,maxx,minn; bool isprime[maxn]; ll a[maxn],b[maxn],c[maxn]; ll dis[maxn],vis[maxn]; ll dp[1010][1010]; string str,s; bool check(ll x){ ll sum=0; for(int i=1;i<=n;i++) if(a[i]<x) sum+=x-a[i]; if(sum>min(x,m)) return 0; else return 1; } #define read read() int main(){ cin>>n>>m; for(int i=1;i<=n;i++) cin>>a[i]; l=0,r=1e9+10; while(l<=r){ ll mid=(l+r)/2; if(check(mid)){ ans=mid; l=mid+1; }else r=mid-1; } cout<<ans<<endl; return 0; }