看到网上有些人是有精度什么做的。我的思路不太一样。
所谓最少的转换其实就是花钱少的给花钱多的人的钱尽量少,多出来那一分钱的误差尽量出在花钱多的人身上。
首先求一个平均值a=sum/n。如果能整除那么这个就简单了。不能整除的时候,得到余数r,这个r的意思是说有r个人最后出了a+1钱,其余人出了a钱。原则上为使转移钱少,让原来花钱多的人,也就是原来花钱大于a的人,数目为x,出a+1的钱。如果x>=r,那么这样原来花钱少于等于a的人只需要出钱补充到a,把这些钱给那些花钱多的人就行了,这样相当于花钱多的人中有r个最终花了a+1的钱。但如果x<r,这样如果还让原来花钱多的人吃亏,那么这x个人中间出的钱肯定有大于a+1的,这样误差就大于了1。所以这时候需要原来出钱少的人除了补充到a之外,还要有r-x个人多转移1钱给原来花钱多的人,多转移的这部分钱一共为r-x。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#define ll long long
using namespace std;
int ConverstoInt(char *a)
{
int num=0,p=-1,L=strlen(a);
for(int i=0; a[i]; ++i)
{
if(isdigit(a[i]))
num=num*10+a[i]-'0';
else if(a[i]=='.')
{
p=i;
break;
}
}
if(p==-1) return num*100;
for(int i=p+1; i<=p+2; ++i)
{
if(i>=L) num=num*10;
else num=num*10+a[i]-'0';
}
return num;
}
int num[1005]= {0},n;
int Count(int val)
{
int cnt=0;
for(int i=0; i<n; ++i)
if(num[i]>val) cnt++;
return cnt;
}
int main()
{
while(scanf("%d",&n)&&n)
{
char str[15];
int sum=0;
for(int i=0; i<n; ++i)
{
scanf("%s",str);
num[i]=ConverstoInt(str);
sum+=num[i];
}
int ans=0;
if(sum%n==0)
{
int ave=sum/n;
for(int i=0; i<n; ++i)
if(num[i]>ave) ans+=num[i]-ave;
}
else
{
int rem=sum%n,quo=sum/n,cnt=Count(quo);
for(int i=0; i<n; ++i)
if(quo>num[i]) ans+=quo-num[i];
if(rem>cnt) ans+=rem-cnt;
}
printf("$%.2lf\n",ans/100.0);
}
return 0;
}