Code Forces 671B - Robin Hood(二分+思维)
题意:n个人,每个人ci的金币,每天最富有的人都会给最贫穷的人1金币,问k天后最富有人和最贫穷的人差了多少金币。
思路:不妨把穷人和富人放在两个时空中
step1: 假设富人不用掏钱,每天给最穷的人1枚金币。
求出最穷的人金币数:x
step2: 假设穷人得不到钱,每天富人有1枚金币不翼而飞。
求出最富的人金币数: y
其中,x与y的值通过二分答案求解。
如果x<y, 则ans=y-x; 若x>=y且sum%n=0,辣么可以平分,答案为0,否则答案为1。
1 #include <iostream> 2 #include <queue> 3 #include <stack> 4 #include <cstdio> 5 #include <vector> 6 #include <map> 7 #include <set> 8 #include <bitset> 9 #include <algorithm> 10 #include <cmath> 11 #include <cstring> 12 #include <cstdlib> 13 #include <string> 14 #include <sstream> 15 #include <time.h> 16 #define x first 17 #define y second 18 #define pb push_back 19 #define mp make_pair 20 #define lson l,m,rt*2 21 #define rson m+1,r,rt*2+1 22 #define mt(A,B) memset(A,B,sizeof(A)) 23 using namespace std; 24 typedef long long LL; 25 const double PI = acos(-1); 26 const int N=1e6+10; 27 const LL mod=1e9+7; 28 const int inf = 0x3f3f3f3f; 29 const LL INF=0x3f3f3f3f3f3f3f3fLL; 30 LL a[N],k,n,ans1,ans2,l,r,m,sum=0; 31 bool check(LL x) 32 { 33 LL res=0; 34 for(int i=0;i<n;i++) 35 { 36 if(x<a[i])break; 37 res+=(x-a[i]); 38 } 39 if(res<=k)return true; 40 else return false; 41 } 42 43 int main() 44 { 45 #ifdef Local 46 freopen("data.txt","r",stdin); 47 #endif 48 ios::sync_with_stdio(false); 49 cin.tie(0); 50 cin>>n>>k; 51 for(int i=0;i<n;i++) 52 { 53 cin>>a[i]; 54 sum+=a[i]; 55 } 56 sort(a,a+n); 57 l=0;r=1e9+1; 58 while(r-l>1) 59 { 60 m=l+(r-l)/2; 61 if(check(m))l=m; 62 else r=m; 63 } 64 ans1=l; 65 for(int i=0;i<n;i++) 66 { 67 a[i]=1e9+1-a[i]; 68 } 69 sort(a,a+n); 70 l=0;r=1e9+1; 71 while(r-l>1) 72 { 73 m=l+(r-l)/2; 74 if(check(m))l=m; 75 else r=m; 76 } 77 ans2=1e9+1-l; 78 //cout<<ans1<<endl; 79 if(ans2>ans1)cout<<ans2-ans1<<endl; 80 else 81 { 82 if(sum%n)puts("1"); 83 else puts("0"); 84 } 85 #ifdef Local 86 cerr << "time: " << (LL) clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl; 87 #endif 88 }