排队

有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;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值