• UVa 10137 & ZOJ 1874 The Trip


      题目大意:n个学生去旅行,旅行中每个学生先垫付,最后平摊所有费用,多退少补,并且支出差距控制在1分钱以内,求最小的交易金额。


                                                                                                         @2013-8-16

      以前在zoj做过,把原来的代码直接提交了,虽然AC了,可是记得原来有问题,再一看确实感觉有问题,竟然AC了...然后就自己重写,写完之后总是WA,就放下了,过一段时间在看,再改,提交,仍是WA,太打击人了,不算难的一道题把我虐成这样...今天看World of Seven上的解法时猛然醒悟,自己一直在纠结精度方面的问题,却没发现在向下截取aver时转换成int后直接除100,变成了整数的除法了...只能无语了...

      自己的思路就是求平均数后向下截取,然后用 总金额-平均数*n 得到少的金额,对每人的花费进行排序,少的金额就通过让后面的人多拿一美分补上。 

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #define MAXN 1010
     4 
     5 int cmp(const void *_a, const void *_b)
     6 {
     7     double *a = (double*)_a;
     8     double *b = (double*)_b;
     9     return *a - *b;
    10 }
    11 
    12 int main(void)
    13 {
    14 #ifdef LOCAL
    15     freopen("in", "r", stdin);
    16 #endif
    17     int n, i, p;
    18     double aver, sum, exchange;
    19     double cost[MAXN];
    20     while (scanf("%d", &n) != EOF)
    21     {
    22         if (n == 0)   break;
    23         sum = 0;
    24         for (i = 0; i < n; i++)
    25         {
    26             scanf("%lf", &cost[i]);
    27             sum += cost[i];
    28         }
    29         aver = sum / n;
    30         aver = (int)(aver*100)/100.0;  /* floor the aver */ 
    31         exchange = 0;
    32         p = (int)((sum-aver*n)/0.01+0.1);
    33         qsort(cost, n, sizeof(double), cmp);    
    34         for (i = n-1; i >= n-p; i--)
    35             if (cost[i] > aver+0.01)
    36                 exchange += cost[i]-(aver+0.01);
    37         for (i = n-p-1; i >= 0; i--)
    38             if (cost[i] > aver)
    39                 exchange += cost[i]-aver;
    40         printf("$%.2lf
    ", exchange);
    41     }
    42     return 0;
    43 }
    View Code

      这个题原来留了好几份代码,现在看看也能看出一些东西,从最初的用c自己用选择排序进行排序到后来用qsort函数排序,到现在用c++的sort,以及代码风格的一些小小改进,发现自己也不是毫无变化了:D,不过长进的也就这些罢了,算法方面还是没什么长进 -_-||

      网上流行另一个版本,World of Seven 上如下描述:

      The problem with this problem may be related to precision error. Here is solution by Neilor:

      double highx = (int)((total/n+0.0099)*100);
      double lowx = (int)((total/n)*100);
      highx /= 100;
      lowx /= 100;
      Where total is the total sum of the money and n is the number of students.

      Then, test each student money if is > than highx or < than lowx, accumulate (student[i]-highx) or (lowx-students[i]), respectively.
      Then, output the variable that have the bigger value.

      不理解为什么可以这样做,也许某天就顿悟了呢?:D   

     

  • 相关阅读:
    redis集群登陆
    锁机制
    关系型数据库事务遵循ACID原则
    前端之Css
    Python之操作redis数据库
    前端之HTML
    Excel之批量改变特定字体颜色(转载)
    jmeter之批量修改请求路径
    Python之time模块
    Python之os模块
  • 原文地址:https://www.cnblogs.com/xiaobaibuhei/p/3169784.html
Copyright © 2020-2023  润新知