未经许可,请匆转载!!!

公司从去年开始注重各级别工程师在算法编码方面的功底,不仅经常组织TopCoder考试,还把考试等级作为每年绩效考评的重要参考(鄙人对此非常反感)。不过反感归反感,但每次考试,如想让代码通过自动在线评测系统,还是得在算法上花一些功夫的。由于之前项目组顾老大非常支持个人练习(狂赞),特地用项目经费买了本编程挑战的书。书到项目组快一年多了,最近才有时间借来看看,也尝试着做书上的题,发现还是挺有趣的,能学到不少平时不注意的东西,也能提前写程序的技巧。由于鄙人做的第一题在提交4次后终于被系统AC,回头细想下,经常做做这些uva的算法题对自己各方面也是个锻炼,特此对每做的算法题做一总结。

读者如若发现分析或者代码有误,或者有更高效,更巧妙的算法,请留言或者联系作者,不胜感激!

contact information:

name: hugehwang       E-mail:fantasynavy0817@126.com     Tele-phone: no

原题描述:

有一群学生团体准备去国外旅游,他们都同意费用均摊,但是在值钱的时候却很不方便。于是有人先付车钱,有人先付餐费等等。等到旅游结束后,再统计每个人出了多少钱,然后出得少的拿钱给出钱多的人,使得每个人所出的钱都相等,如果无法使每个人出的钱相等,那就要求只能相差在一分钱之内。你现在的任务是:给你每个学生的旅游时出的费用,请你算出最少有多少钱要交换才能使每个人出的钱相等或在允许的误差之内。

输入数据:

每组测试数据的第一行有一个数,它代表本次旅游的总人数。接下来的n行为每个学生旅游时出的钱,最小的单位为一分钱。学生的总人数不会超过1000人,每个人出的钱不会超过$10000.00元。n=0时表示输入结束。

输出数据:

对每组数据输出一行,输出最少需要交换多少钱就能使得每个人所出的钱尽可能接近。 格式请参考如下sample.

sample input

3

10.00

20.00

30.00

4

15.00

15.01

3.00

3.01

5

5000.00

11.11

11.11

11.11

11.11

0

sample output

$10.00

$11.99

$3991.11

分析:

初次接触此题,很容易就会想到解法为求平均值。但此题在求平均值的基础上增加了条件,那就是误差可以在1美分之内,其实本质上也就是平均值可以在0~1之间浮动。现在假设平均值下限值记为avg【向下取整】,那么平均值的上限值则可以记为avg+1【向上取整】。为了使每个人出的钱都接近相等,那就必须让每个人出的钱都尽可能地在这里定义的两个平均值之间,那么出的钱少于这个平均值的人所补的钱之和或者出的钱高于这个平均值的人所收的钱之和就是我们想要计算的总的要交换的钱了。为了让交换的钱尽可以地少,那就必须让要收钱的人尽可以少收钱或者要出钱的人尽可能少出钱。于是,要收钱的人以avg+1为基准而要出钱的人以avg为基准。这样就解决了我们的问题了。

#include #include using namespace std;
int money[1000];
int main()
{
//freopen("H:\\algorithm_study\\uva_the_trip\\sample_input.txt", "r", stdin);
//person in trip
int persons;
while (cin >> persons && persons)
{
int total = 0;
//read money, in format of float
for (int i = 0; i < persons; ++i)
{
int a = 0, b = 0;
cin >> a;
cin.get();
cin >> b;
money[i] = a * 100 + b;
total += money[i];
}
//calculate average
int avg = total / persons;
int avg_add = avg + 1;
//calculate minmize
int remainder = 0;
int diff = 0;
int min = 0;
for (int i = 0; i < persons; ++i)
{
if (money[i] > avg_add)
{
diff = money[i] - avg_add;
remainder -= diff;
min += diff;
}
else if (money[i] < avg)
{
diff = avg - money[i];
remainder += diff;
}
}
if (remainder > 0)
{
min += remainder;
}
cout.setf(ios::fixed | ios::showpoint);
cout.precision(2);
cout << "$" << (double)min / 100 << endl;
}
return 0;
}

后记:

在解决此题的过程中,出现了5次在uva上提交不过的情况,最终发现是读取浮点数的方式不对。不过到现在我也没有明白为何先定义一个double型的变量d,然后再cin >> d;在uva上会不通过?在调试的过程中,发现如果要读取的浮点型数据是9999.99,那么d的值居然是9999.989999。怪哉!!!?

在网上也看了不少人的思路,很多人都是先由钱的总数整除总人数计算出一个平均值,其实这个是向下取整,然后以此平均值为基准计算大于这个平均值的人要收的钱的总数和少于这个平均值的人要出的钱的总数,再选出两个总数中的小的那个。由上面我们分析的可知,这种算法最小的不见得是正确的。另外,【以下见解纯属技术讨论,不含有任何诋毁、攻击等意图,如让读者产生误解,纯属意外!!!】对网上一个分析此题的想法印象特别深刻,大概是在这里所说的错误的思路的基础上再处理一个他认为是特殊的情况,数据由0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.03组成。虽然他给出的代码通过了uva的评测,但在我看来这种代码就是奔着结果去的,而且也不是很好理解。

算法的背后都是有着某种规律,可以由特殊推向一般,也可以由一般推向特殊。如果一种算法需要考虑对那些不具有特殊性的数据进行特殊处理的话,那么可以反证此算法是错误的。

以上文字纯属属个人研究所得,这里还是要感谢http://www.hankcs.com/program/uva-q10137-the-trip.html这篇文章的作者。让我正确的找到了平均的上限和下限,本以为下限是avg-1,上限是avg+1.

欢迎大家指正!!!

UVa Q10137: The Trip (旅行)相关推荐

  1. UVA 11100 The Trip, 2007

    https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  2. 贪心思维 专题记录 2017-7-21

    A.UVa 10382 - Watering Grass 题目大意: 有一块草坪,长为l,宽为w,在它的水平中心线上有n个位置可以安装喷水装置,各个位置上的喷水装置的覆盖范围为以它们自己的半径ri为圆 ...

  3. EF里一对一、一对多、多对多关系的配置和级联删除

    EF里一对一.一对多.多对多关系的配置和级联删除 本章节开始了解EF的各种关系.如果你对EF里实体间的各种关系还不是很熟悉,可以看看我的思路,能帮你更快的理解. I.实体间一对一的关系 添加一个Per ...

  4. π-Algorithmist分类题目(2)

    原题网站:Algorithmist,http://www.algorithmist.com/index.php/Main_Page π-Algorithmist分类题目(2) Set Theory U ...

  5. π-Algorithmist分类题目(1)

    原题网站:Algorithmist,http://www.algorithmist.com/index.php/Main_Page π-Algorithmist分类题目(1) Sorting UVAL ...

  6. learning的反义词英文_英语同义词反义词

    初中英语同义词反义词 初中英语同义词 above / over 在--上方 almost / nearly 几乎:差不多 also / too 也:同样 among / between 在--之间 a ...

  7. 国外生活必备的英文词汇

    餐具: coffee pot 咖啡壶 coffee cup 咖啡杯 paper towel 纸巾 napkin 餐巾 table cloth 桌布 tea -pot 茶壶 tea set 茶具 tea ...

  8. 151个容易混淆拼错的英文单词

    1) quite 相当 quiet 安静地 2) affect v 影响, 假装 effect n 结果, 影响 3) adapt 适应 adopt 采用 adept 内行 4) angel 天使 a ...

  9. sicily题目分类

    sicily题目分类 1. 编程入门 2. 数据结构 3. 字符串 4. 排序 5. 图遍历 6. 图算法 7. 搜索:剪枝,启发式搜索 8. 动态规划/递推 9. 分治/递归 10. 贪心 11. ...

最新文章

  1. Lucene:基于Java的全文检索引擎简介(转载)
  2. 一个JS对话框,可以显示其它页面,
  3. TCP/IP协议的编写《转载》
  4. 前缀列表---Prefix-List
  5. ASP.NET网络编程中经常用到的27个函数集
  6. ALV字段编辑时,输入长度受限制解决方法
  7. linux-搜索查找类
  8. mysql 客服_MySQL
  9. 工行金融级微服务架构的实践
  10. Java高并发、分布式框架,从无到有微服务架构设计
  11. Jersey +jetty 实现微服务(一)
  12. vue cli3 一键 build 区分测试环境和正式环境
  13. python关闭word_python自动化办公:玩转word之样式秘笈
  14. 蚂蚁笔记 linux安装教程,简年14:蚂蚁笔记(Leanote)快速部署指南
  15. 为什么会有hash冲突?
  16. Phil Coulson
  17. (BT)工作笔记(1)
  18. BBN: Bilateral-Branch Network with Cumulative Learning for Long-Tailed Visual Recognition
  19. 包裹侠快递查询_全球顶尖技术精英汇聚菜鸟 准备帮助快递攻破体积测量难题...
  20. 10大开源的快速开发平台

热门文章

  1. GBASE赛事 | ICDIS数据库参数调优大赛开启报名
  2. vue---父子组件间的通信
  3. 奋斗就是每一天都很难,但一年一年却越来越容易;不奋斗就是每天都很容易,但一天一天却越来越难
  4. 蓝牙控制小车c语言程序,手把手教你做蓝牙小车(一)
  5. POJ 1589 Unix ls
  6. mac系统占用100多G怎么清除 mac内存系统占用了好多怎么清理
  7. 2017-9-17 PAT考试记
  8. Deepstream 6.1.1 以及 Python Binding Docker 安装
  9. [蓝桥杯][历届试题]蚂蚁感冒
  10. Linux 使用sed指令插入到指定的行的上一行或者下一行