【模拟】Codeforces 671B Robin Hood

题目链接:

  http://codeforces.com/problemset/problem/671/B

题目大意:

  N个人,每个人有Ci钱,现在有一个人劫富济贫,从最富的人之一拿走1元,再给最穷的人。总共K次,问最后贫富差距。

  钱被拿走是立刻结算,所以可能拿走后这个人变最穷的人再还回去。

  最富或最穷的人可能有多个,随机选择,并且不会影响最终答案。

  (1 ≤ n ≤ 500 000, 0 ≤ k ≤ 109)

题目思路:

  【模拟】

  直接排序离散化数据,之后模拟就行。

  细节挺多的要处理清楚。

 

  1 //
  2 //by coolxxx
  3 //#include<bits/stdc++.h>
  4 #include<iostream>
  5 #include<algorithm>
  6 #include<string>
  7 #include<iomanip>
  8 #include<map>
  9 #include<memory.h>
 10 #include<time.h>
 11 #include<stdio.h>
 12 #include<stdlib.h>
 13 #include<string.h>
 14 //#include<stdbool.h>
 15 #include<math.h>
 16 #define min(a,b) ((a)<(b)?(a):(b))
 17 #define max(a,b) ((a)>(b)?(a):(b))
 18 #define abs(a) ((a)>0?(a):(-(a)))
 19 #define lowbit(a) (a&(-a))
 20 #define sqr(a) ((a)*(a))
 21 #define swap(a,b) ((a)^=(b),(b)^=(a),(a)^=(b))
 22 #define mem(a,b) memset(a,b,sizeof(a))
 23 #define eps (1e-8)
 24 #define J 10
 25 #define mod 1000000007
 26 #define MAX 0x7f7f7f7f
 27 #define PI 3.14159265358979323
 28 #define N 500004
 29 using namespace std;
 30 typedef long long LL;
 31 int cas,cass;
 32 int n,m,lll,ans;
 33 double anss;
 34 LL b[N];
 35 LL sum;
 36 struct xxx
 37 {
 38     LL num,large;
 39 }a[N];
 40 bool cmp(LL aa,LL bb)
 41 {
 42     return aa<bb;
 43 }
 44 int work()
 45 {
 46     int i;
 47     LL k,maxx,minn;
 48     k=m;i=lll;
 49     while(i && k>=a[i].num*(a[i].large-a[i-1].large))
 50     {
 51         k-=a[i].num*(a[i].large-a[i-1].large);
 52         a[i-1].num+=a[i].num;
 53         a[i--].num=0;
 54         if(!i)return (sum%n!=0);
 55     }
 56     maxx=a[i].large-k/a[i].num;
 57     a[i+1].large=maxx,a[i+1].num=a[i].num-k%a[i].num;
 58     a[i].large=maxx-1;a[i].num-=a[i+1].num;
 59     lll=i+1;
 60     //==========================================
 61     k=m;i=1;
 62     while(k>0 && k>=a[i].num*(a[i+1].large-a[i].large) && a[i].large<maxx)
 63     {
 64         if(a[i].num==0){i++;continue;}
 65         k-=a[i].num*(a[i+1].large-a[i].large);
 66         a[i+1].num+=a[i].num;
 67         a[i++].num=0;
 68     }
 69     if(a[i].large>=maxx)return (sum%n!=0);
 70     if(a[i+1].num==0)
 71         minn=a[i].large+k/a[i].num;
 72     else
 73         minn=a[i].large+k/(a[i].num);
 74     return maxx-minn;
 75 }
 76 int main()
 77 {
 78     #ifndef ONLINE_JUDGE
 79     freopen("1.txt","r",stdin);
 80 //    freopen("2.txt","w",stdout);
 81     #endif
 82     int i,j;
 83 //    for(scanf("%d",&cas);cas;cas--)
 84 //    for(scanf("%d",&cas),cass=1;cass<=cas;cass++)
 85 //    while(~scanf("%s",s))
 86     while(~scanf("%d",&n))
 87     {
 88         scanf("%d",&m);
 89         sum=0;mem(a,0);
 90         for(i=1;i<=n;i++)
 91         {
 92             scanf("%d",&b[i]);
 93             sum+=b[i];
 94         }
 95         sort(b+1,b+1+n,cmp);
 96         lll=1;a[lll].large=b[1];a[lll].num=1;
 97         for(i=2;i<=n;i++)
 98         {
 99             if(b[i]==b[i-1])a[lll].num++;
100             else a[++lll].large=b[i],a[lll].num=1;
101         }
102         j=work();
103         printf("%d\n",j);
104     }
105     return 0;
106 }
107 /*
108 //
109 
110 //
111 */
View Code

 

posted @ 2016-08-18 18:26  Cool639zhu  阅读(419)  评论(0编辑  收藏  举报