您的位置:首页 > 其它

UVa:10137 The Trip

2013-12-17 12:20 375 查看
看到网上有些人是有精度什么做的。我的思路不太一样。

所谓最少的转换其实就是花钱少的给花钱多的人的钱尽量少,多出来那一分钱的误差尽量出在花钱多的人身上。

首先求一个平均值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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: