有N队学生,编号分别为1,2,…,n。每队上有若干学生,但学生总数必为n的倍数.可以在任一队上移动若干个学生。移动的规则是:在编号为1的队上移动的学生,只能移到编号为2的队上;在编号为n的队上移动的学生,只能移到编号为n-1的队上;其它队上移动的学生,可以移到相邻左边或右边的队上。现在要求找出一种移动方法,用最少的移动次数使每队上的学生人都一样多。例如:n=3,3队学生分别为:① 3 ② 4 ③ 2 移动一次可以达到目的:从②移动一名学生到③队中即可实现每队人数相同。
Input:
要求从标准输入获得两类数据,值得范围正整数(1~100之间),表示队数和每队人数,第一行输入队数,第二行按队数输入每队人数。每行多个数值之间空格隔开。
Output:
程序输出需要移动的次数。
Input Sample:
3
3 4 2
Output Sample:
1
代码:
#include<stdio.h>
#include<malloc.h>
void shift(int *array,int n, int avg)
{
static int times = 0;
int i;
/* for(i=0;i<n;i++)
{
printf("array[%d]:%d\n",i,*(array+i));
}*/
for(i=0;i<n;i++)//从左往右循环
{
if(*(array+i)>avg)//如果大于平均数,则将多余的往后挪
{
int sh = *(array+i)-avg;
*(array+i+1)+=sh;
*(array+i)-=sh;
times+=sh;
}
else if(*(array+i)<avg)//如果小于平均数
{
int j = i+1;
int sh = avg-*(array+i);
while(j<n-1 && *(array+j)<=avg)//则往后遍历,找到大于平均数的那一队
j++;
while(j>i)//将本队缺的人数往前挪,一直挪到本队
{
*(array+j-1)+=sh;
*(array+j)-=sh;
times+=sh;
j--;
}
}
}
printf("次数;%d\n",times);
}
int main(int argc,char *argv[])
{
int nn = 0;
int i,sum = 0;
scanf("%d",&nn);//输入队数
int *array = (int*)malloc(nn*sizeof(int));
for(i = 0;i<nn;i++)//循环输入每队的初始人数
{
scanf("%d",array+i);
sum += *(array+i);//计算总人数
}
if(sum%nn != 0)//总人数必须为队数n的倍数
{
printf("error input!\n");
exit(-1);
}
shift(array,nn,sum/nn);//移动
return 0;
}