一种思路:
交易额中肯定包含少交的人补交的钱。注意到,0.01----0.01*(n-1)这部分在求平均的时候被抹掉了,所以,还要讨论这个部分。这个部分遵循的原则就是,多交了钱的每个人先承担抹掉的0.01,因为这样的话就可以减少交易次数,交易额也就可能最小了。如果多交了钱的人数*0.01 == 原始总数 - 平均*n,那么少交的人就不用再补交了。否则就要补交(原始总数 - 平均*n -多交了钱的人数*0.01 )。因此就有了一下程序:
#include<stdio.h>
int main()
{
int n;
double money[1001];
double average,sum;
int i,count;
while(1)
{
scanf("%d",&n);/*get the number of the student*/
if(0 == n)
break;
average = 0;
sum = 0;
count = 0;
for(i = 0;i < n;i ++)/*get money of each stu*/
{
scanf("%lf",&money[i]);
average += money[i];
}
money[1000] = average;/*sum = money[1000]*/
average /= n;
average = ((int)(average *100))/100.0;
for(i = 0;i < n;i ++)
{
if(money[i] <= average)/*注意这里的等号*/
{
sum +=(average - money[i]);
count ++;
}
}
count = n - count;//计算多交的人数
if(0.01*count < money[1000] - n*average)//处理抹掉的小数部分
sum += (money[1000] - n*average - 0.01*count);
printf("$%.2lf\n",sum);
}
return 0;
}
另一种思路:
少交的人,按平均补交上来;多交的人,先按少0.01也就是(交的 - (平均 + 0.01))拿钱(因为要使交易额最小,所以要多出了钱的人少拿点),这些少拿的人,实际上比平均多交了0.01。这些0.01主要用来磨平求平均值时损失掉的小数部分。这里可以参考博客http://blog.csdn.net/mobius_strip/article/details/13762783