UVa:10137 The Trip

看到网上有些人是有精度什么做的。我的思路不太一样。

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

首先求一个平均值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;
}


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值