Descrição
regime comunista está tentando redistribuir a riqueza em uma aldeia. Eles decidiram sentar-se todos
em torno de uma mesa circular. Em primeiro lugar, todo mundo tem convertido todas as suas propriedades para moedas de igual valor,
de modo que o número total de moedas é divisível pelo número de pessoas na aldeia. Finalmente, cada
pessoa dá um número de moedas para a pessoa à sua direita e um número de moedas para a pessoa à sua esquerda,
de tal forma que, no final, todo mundo tem o mesmo número de moedas. Dado o número de moedas de cada pessoa,
calcular o número mínimo de moedas que devem ser transferidas usando este método de modo que todos
tem o mesmo número de moedas.
Entrada
Há um número de entradas. Cada entrada começa com n (n <1000001), o número de pessoas na
aldeia. n linhas seguem, dando o número de moedas de cada pessoa na aldeia, no sentido anti-horário
fim ao redor da mesa. O número total de moedas vai caber dentro de um número inteiro de 64 bits sem sinal.
Saída
Para cada entrada, saída o número mínimo de moedas que devem ser transferidos em uma única linha.
Entrada simples
3
100
100
100
4
1
2
5
4
saída simples
0
4
Análise das idéias:
Uma vez que o número total de moedas do que o número total de pessoas em um inteiro, usamos m para representar o número, ou seja, depois de múltiplos pontos de terminar moedas, todo mundo tem m moedas mãos, usamos um array para representar um
每个人在分硬币之前的每个人的硬币数,用x数组来表示第i个人给他前一个人的硬币数,那么就有A[i]-x[i]+x[i+1]=m,即x[i+1]=x[i]-A[i]+m;
将xi往后推则有:
x2=x1-A[i]+m;
x3=x2-A2+m=x1-A[1]-A[2]+2*m;
x4=x3-A3+m=x1-A[1]-A[2]-A[3]+3*m;
于是我们为了简化这些式子,用C[1]=A[1]-m,C[2]=c[1]+A[2]-m ··· ···
则有
x2=x1-C[1];
x3=x1-C[2];
x4=x1-C[3];
···
我们最终要求的就是|x1|+|x1-C1|+|x1-C2|+···+|x1-Cn-1|最小,则我们取得x1应该为ci的中位数,最终统计答案即可。
开long long
附上代码:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int N=1e6+10; 6 long long a[N],c[N],m,n,sum; 7 int main(){ 8 while(scanf("%lld",&n)==1){ 9 memset(a,0,sizeof(a)); 10 memset(c,0,sizeof(c)); 11 sum=0; //用于计算sum 12 for(int i=1;i<=n;++i){ 13 scanf("%lld",&a[i]); 14 sum+=a[i]; 15 } 16 m=sum/n; 17 for(int i=1;i<=n;++i) 18 c[i]=c[i-1]+a[i]-m; //由前面的公式得到 19 sort(c+1,c+n+1); 20 long long x1=c[n/2],ans=0; //x1取c[]的中位数 21 for(int i=1;i<=n;++i) 22 ans+=abs(x1-c[i]);//统计答案. 23 printf("%lld\n",ans); 24 } 25 return 0; 26 }