2415 : 吃糖果
题目描述
南阳理工附属幼儿园有m个小胖友。每天,这些小胖友都要吃很多很多糖果,Miss.miao是负责分发糖果的老师,由于工作量巨大,Miss.miao经常不能保证每个小胖友分到的糖果数量是一样的。如果存在两个小胖友的糖果数量的差值超过k,那么这些小胖友就会很不开心。
现在,假设给出你每个小胖友的糖果数量,你作为这些小胖友中最聪明的一个,Miss.Miao老师要你协助她重新分配糖果,使得任意两个小胖友的糖果数量的差值不超过k。每一次,你可以将一个小胖友手里的一颗糖果拿给另外一个小胖友,但为了显示你的聪明才智,你必须用最少的次数完成任务。顽张ってください
输入
输入包含多组数据,每组包括两行,第一行两个数m,k,表示小胖友的数量和差值k(m<=1e6,k<=1e9)。
接下来一行m个正整数Ai,表示Miss.miao分给每个小胖友的糖果数量(Ai<=1e6)。
输出
对于每组数据,输出“Case #x: ans”,x表示当前是第几组数据,ans表示最少操作次数。
样例输入
3 1
1 2 3
4 3
1 5 1 10
样例输出
Case #1: 1
Case #2: 4
(说是中档题,可是我这种小菜怎么能A。大佬们都太棒了!)
当最大的和最小的数相差不大于k,那么其他的就可能定不会大于k,所以拿糖果的时候,只需要减小最大值和最小值的差就好了。可是如果每次只变化一对最大最小值,肯定会超时,所以要桶排序,每次把最大值和最小值的一桶都给更新一下,就会减小更新次数。注意结果要用long long。
#include<map> #include<set> #include<queue> #include<math.h> #include<vector> #include<string> #include<stdio.h> #include<iostream> #include<string.h> #include<algorithm> #define inf 0x3f3f3f #define ll long long #define maxn 1000005 using namespace std; int book[maxn]; int main(){ int n,m,t=0; while(~scanf("%d%d",&n,&m)){ int q1=-maxn,q2=maxn; memset(book,0,sizeof(book)); for(int i=0;i<n;i++){int x; scanf("%d",&x); q1=max(q1,x);q2=min(q2,x); book[x]++; } ll ans=0; int big=q1,small=q2; while(big-small>m){ int y=min(book[big],book[small]);//cout<<y<<endl; ans+=y;book[big]-=y;book[small]-=y; book[big-1]+=y;book[small+1]+=y; if(book[big]==0)big--; if(book[small]==0)small++; } printf("Case #%d: %lld ",++t,ans); } }