排队

来源:互联网 发布:linux移动非空文件夹 编辑:程序博客网 时间:2024/05/01 05:34
有N队学生,编号分别为1,2,…,n。每队上有若干学生,但学生总数必为n的倍数.可以在任一队上移动若干个学生。移动的规则是:在编号为1的队上移动的学生,只能移到编号为2的队上;在编号为n的队上移动的学生,只能移到编号为n-1的队上;其它队上移动的学生,可以移到相邻左边或右边的队上。现在要求找出一种移动方法,用最少的移动次数使每队上的学生人都一样多。例如:n=3,3队学生分别为:① 3 ② 4 ③ 2 移动一次可以达到目的:从②移动一名学生到③队中即可实现每队人数相同。Input: 要求从标准输入获得两类数据,值得范围正整数(1~100之间),表示队数和每队人数,第一行输入队数,第二行按队数输入每队人数。每行多个数值之间空格隔开。Output: 程序输出需要移动的次数。Input Sample: 33 4 2Output 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
原创粉丝点击