题目保证有解即纸牌总数能被人数整除(N|T)每个人持有纸牌a[1]...a[m],我们可以先考虑第一个人
1.若a[1]>T/M,则第一个人需要给第二个人c[1]-T/M张纸牌,即把c[2]加上c[1]-T/M。
2.若a[1]<T/M,则第一个人需要拿第二个人c[1]-T/M张纸牌,即把c[2]减去T/M-c[1]。
我们可以按照这种方法依次考虑2~M个人。即使某个时刻有某个c[i]被减为负数也没有关系,因为接下来c[i]就会从c[i+1]处拿纸牌。
代码
#include<bits/stdc++.h>
using namespace std;
int m,a[105],T,ans;
int main(){
scanf("%d",&m);
for(int i=1;i<=m;++i){
scanf("%d",&a[i]);
T+=a[i];
}
T/=m;
for(int i=1;i<=m;++i){
a[i]-=T;
}
for(int i=1;i<=m;++i){
if(a[i]!=0){
a[i+1]+=a[i];
ans++;
}
}
printf("%d",ans);
return 0;
}
在此问题上还可进行一个拓展,若每次只能拿一张牌,思路也跟上面相同,最小步数就是
(sum_{i=1}^M) (mid)i*T/M-G[i](mid) ,其中G是a的前缀和,即 G[i]= (sum_{j=1}^i) a[i]
其中的含义是每个“前缀”最初有G[i]张纸牌,最后会有i*T/M张纸牌。
如果我们设A[i]=a[i]-T/M,即一开始就让每个人手中的纸牌数都减去T/M,并且最终让每个人手里都只有0张纸牌,答案依然不变,就是
(sum_{i=1}^M) (mid)S[i](mid)其中S是A的前缀和即 S[i]=(sum_{j=1}^i)A[i]