有n堆纸牌(2≤n≤200),排成一行,编号分别为1,2,…n。 已知每堆纸牌有一定的张数,且张数之和均为n的倍数。移动各堆中的任意张纸牌,使每堆的数量达到相同,且移动次数最少。 移动规则: 每次可以移动任意的张数,第1堆可以移向第2堆,第2堆可以移向第1堆或第3堆,。。。。。。第n 堆只可以移向第n -1堆。
#include "stdio.h"
#include "stdlib.h"
int and(int a[],int n)
{
int i,sum=0;
for(i=0;i<n;i++)
sum=sum+a[i];
if(sum%n!=0)
return -1;
return sum/n;
}
int move(int a[],int n,int flag)
{
int *b,i,j;
int flag1=0;
int number=0;
b=(int *)malloc(sizeof(int));
for(i=0;i<n;i++)
b[i]=a[i]-flag;
for(i=0;i<n;i++)
{
if(b[i]<0)
{
for(j=i;j>=0;j--) //向前扫描进行填充
if(b[j]>0)
{
if(b[j]+b[i]>=0)
{
number=number+(i-j)*(0-b[i]);
b[j]=b[j]+b[i];
flag1=11;
break;
}
else
{
number=number+(i-j)*(0-b[i]);
b[j]=b[j]+b[i];
b[i]=b[i]+b[j];
}
}
if(flag1!=11)
{
for(j=i;j<n;j++) //向后扫描进行填充
if(b[j]>0)
{
if(b[j]+b[i]>=0)
{
number=number+(j-i)*(0-b[i]);
b[j]=b[j]+b[i];
flag1=0;
break;
}
else
{
number=number+(j-i)*b[j];
b[i]=b[i]+b[j];
b[j]=0;
}
}
}
}
}
printf("%d\n",number);
return 0;
}
int main()
{
int i;
int *a;
int n;
int flag;
while(1)
{
scanf("%d",&n);
a=(int *)malloc(n*sizeof(int));
for(i=0;i<n;i++)
scanf("%d",&a[i]);
if((flag=and(a,n))==-1)
{
printf("silly linlihao159!\n");
}
move(a,n,flag);
}
return 0;
}