The Trip programming_Challengs Uva_OnlineJudge

一种思路:
交易额中肯定包含少交的人补交的钱。注意到,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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值