传送门
题意
(N)个人拍成一排,每个人有(C_{i})张牌,每个操作可以让任意一个人把一张牌给他旁边的一个人,求最小操作数使得每个人手中牌数相等
数据范围
(1 <N < 100)
(1leq C_{i}leq 10000)
题解
显然,只有牌总数(sum)能被(N)整除时才有解,本题保证了牌的总数是(N)的倍数所以一定有解
从第一个开始,
-
若(C_{1} > frac{sum}{N}),那么第一个人需要给第二个人(C_{1}-frac{sum}{N}),即(C_{2})加上(frac{sum}{N})
-
若(C_{1} < frac{sum}{N}),那么第一个人需要从第二个人拿(frac{sum}{N}-C_{1}),即(C_{2})减去(frac{sum}{N})
某个人被减成负数也没有关系,因为顺序不固定,那么最少操作就是:(sum_{i=1}^{N}left|i cdot frac{s}{N}-G i ight|),其中G是前缀和
如果假设 (A_{i} = C_{i} - frac{sum}{N}),即一开始就让每个人手中的纸牌都减去(frac{sum}{N}),并最终让每个人手里都恰好有(0)张,
答案显然不变为:(sum_{i=1}^{N}left|S_{i} ight|),其中(S)是(A)的前缀和即(S[i]=sum_{j=1}^{i} A[j])
Code
#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for(int i=a;i<n;i++)
#define ll long long
const int N=110;
int n;
int a[N];
int main(){
scanf("%d",&n);
int sum=0;
rep(i,1,n+1) scanf("%d",&a[i]),sum+=a[i];
int avg=sum/n;
int ans=0;
rep(i,1,n){
if(a[i]>avg) a[i+1]+=a[i]-avg,ans++;
else if(a[i]<avg) a[i+1]-=avg-a[i],ans++;
}
printf("%d
",ans);
}