【问题描述】
有 n 堆纸牌,编号分别为 1,2,…,n。每堆上有若干张,但纸牌总数必为 n 的倍数。可以在任一堆上取若于张纸牌,然后移动。
移牌规则为:在编号为 1 堆上取的纸牌,只能移到编号为 2 的堆上;在编号为 n 的堆上取的纸牌,只能移到编号为 n-1 的堆上;其他堆上取的纸牌,可以移到相邻左边或右边的堆上。
现在要求找出一种移动方法,用最少的移动次数使每堆上纸牌数都一样多。
【输入格式】
第 1 行为整数n,表示有n堆纸牌。
第 2 行有 n 个整数:A1 A2 … An ,Ai 表示第 i 堆纸牌初始数量。
【输出格式】
所有堆均达到相等时的最少移动次数。
【输入样例】
4
9 8 17 6
【输出样例】
3
【样例解释】
有4 堆纸牌,数量分别为:9、8、17、6,移动3次可达到目的:
第1次:从第 3 堆取 4 张牌放到第 3 堆:9、8、13、10
第2次:从第 3 堆取 3 张牌放到第 2 堆:9、11、10、10
第3次:从第 3 堆取 1 张牌放到第 1 堆:10、10、10、10
【数据范围】
1 <= N <= 100 , l<= Ai <=10000
【来源】
NOIP2002提高组第1题
输入数据时算出总张数,一次循环,多了就往给下堆,少了就找下一堆要,每次给和要就将次数加1。
#include<cstdio>
#define maxn 100005
using namespace std;
int n,sum=0,mid,ans=0;
int a[maxn];
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
sum+=a[i];
}
mid=sum/n;
for(int i=1;i<=n;i++)
{
if(a[i]>mid) a[i+1]+=a[i]-mid,ans++;
if(a[i]<mid) a[i+1]-=mid-a[i],ans++;
}
printf("%d",ans);
return 0;
}