扑克牌——joker

description

现有(n)种牌若干张和(m)(joker).凑齐(n)种牌各一张可凑出一副牌,(joker)可以当作任意一张牌,但一副牌中至多只能出现一张(joker),试问之多能凑出多少副牌.

solution

神二分.由题意,我们分析可得,对于(k)副牌,(joker)至多为(k)张,这样可以保证每副牌至多1张(joker),于是乎可以据此二分,复杂度(Omicron(n log 2147483648))

code

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#define R register
#define next MabLcdG
#define mod 1
#define debug puts("mlg")
#define Mod(x) ((x%mod+mod)%mod)
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
inline ll read();
inline void write(ll x);
inline void writesp(ll x);
inline void writeln(ll x);
ll n,m;
ll val[52];
ll ans;
bool check(ll k){
	ll sum=0;
	for(R ll i=1;i<=n;i++){
		if(val[i]<k) sum+=k-val[i];
	}
	return sum<=k&&sum<=m;
}
ll l,r;
int main(){
	n=read();m=read();
	for(R ll i=1;i<=n;i++){
		val[i]=read();
	}
	l=0;r=600000000;
	while(l+1<r){
		ll mid=l+r>>1;
		if(check(mid)) l=mid;
		else r=mid-1;
	}	
	writeln(check(l+1)?l+1:l);
}
inline ll read(){ll x=0,t=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') t=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*t;}
inline void write(ll x){if(x<0){putchar('-');x=-x;}if(x<=9){putchar(x+'0');return;}write(x/10);putchar(x%10+'0');}
inline void writesp(ll x){write(x);putchar(' ');}
inline void writeln(ll x){write(x);putchar('
');}
原文地址:https://www.cnblogs.com/ylwtsq/p/13444003.html