PTA题目:7-9 抢红包 (25分)
没有人没抢过红包吧…… 这里给出N个人之间互相发红包、抢红包的记录,请你统计一下他们抢红包的收获。
输入格式:
输入第一行给出一个正整数N(≤104),即参与发红包和抢红包的总人数,则这些人从1到N编号。随后N行,第i行给出编号为i的人发红包的记录,格式如下:
KN1P1⋯NKPK
其中K(0≤K≤20)是发出去的红包个数,Ni是抢到红包的人的编号,Pi(>0)是其抢到的红包金额(以分为单位)。注意:对于同一个人发出的红包,每人最多只能抢1次,不能重复抢。
输出格式:
按照收入金额从高到低的递减顺序输出每个人的编号和收入金额(以元为单位,输出小数点后2位)。每个人的信息占一行,两数字间有1个空格。如果收入金额有并列,则按抢到红包的个数递减输出;如果还有并列,则按个人编号递增输出。
输入样例:
10
3 2 22 10 58 8 125
5 1 345 3 211 5 233 7 13 8 101
1 7 8800
2 1 1000 2 1000
2 4 250 10 320
6 5 11 9 22 8 33 7 44 10 55 4 2
1 3 8800
2 1 23 2 123
1 8 250
4 2 121 4 516 7 112 9 10
输出样例:
1 11.63
2 3.63
8 3.63
3 2.11
7 1.69
6 -1.67
9 -2.18
10 -3.26
5 -3.26
4 -12.32
分析:
这是和之前的德才论一样类型的题目,给出大量数据,然后按一定的规则排序。
具体考点:结构体,结构体指针,qsort排序,对于浮点数误差的理解。
大的框架我是完全能写出来的。
但细节上出了问题。
排序函数参数cmp
int cmp(const void *a,const void *b)
{struct people *A = (struct people *)a;struct people *B = (struct people *)b;if(fabs(A->mon>B->mon)>=1e-15){if(A->mon>B->mon) return -1;else if(A->mon<B->mon) return 1;}// if(A->redc>B->redc) return -1;
// else if(A->redc < B->redc) return 1;
// if(A->id > B->id) return 1;
// else if(A->id < B->id) return -1;
}
起初知识两行指针赋值+三对排序。但结果和案例不同。开头三位是1,8,2。但答案是1,2,8。经反复的注释,控制变量思想,发现应该是第三重排序,也就是id来控制2在8的前面,但有没有这段代码都一样,也就是说明没有起作用。
思考认为,或许是double的误差,以前见到过,是说double不能简单地说==/!= , 因为他的有效位数一定,而之后位就会有波动。于是我怀疑,对于2和8的排序,或许根本没有进入第三重,而在第一重就因为所谓的误差走了return的路。
那么,不妨承认误差。这才有了上面的代码。
来源:https://blog.csdn.net/Rex_WUST/article/details/89219529
我便仿照这修改,如上。却发现之后的排序却变得一团糟。似乎这样写不行。
于是,这就想办法消除误差。发现题中最后输出的都是两位小数。我就想,或许实现对浮点数保留至2位在进行比较,不就行了吗。说动手就动手。
我学习了这位老师的思路:https://blog.csdn.net/weixin_42643216/article/details/100788103
便补充
for(i=1;i<=N;i++)
{if(money[i].mon>0){f = money[i].mon + 0.005;temp = f*100;f = 1.0*temp/100;money[i].mon = f; }}
他确实起到了一些作用,但这个方法仅适用于正数,我的负数四舍五入,最后结果和理论输出偏了0.01.于是pta判断还是错误。
然后我偷鸡着改了改,上述操作只针对正数,然后就AC了。
附上代码:
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
struct people{int id;double mon;int redc;
}money[20000],t;int cmp(const void *a,const void *b)
{struct people *A = (struct people *)a;struct people *B = (struct people *)b;if(A->mon>B->mon) return -1;else if(A->mon<B->mon) return 1;if(A->redc>B->redc) return -1;else if(A->redc < B->redc) return 1;if(A->id > B->id) return 1;else if(A->id < B->id) return -1;
}int main()
{int i,N,id,mon,n,j,temp;double f;scanf("%d",&N);for(i=1;i<=N;i++){money[i].mon = 0;money[i].redc = 0;money[i].id = i;}for(i=1;i<=N;i++){scanf("%d",&n);for(j=1;j<=n;j++){scanf("%d %d",&id,&mon);money[i].mon -= 1.0*mon/100;money[id].mon += 1.0*mon/100;money[id].redc++;} }for(i=1;i<=N;i++){if(money[i].mon>0){f = money[i].mon + 0.005;temp = f*100;f = 1.0*temp/100;money[i].mon = f; }}qsort(money+1,N,sizeof(struct people),cmp);for(i=1;i<=N;i++){printf("%d %.2lf\n",money[i].id,money[i].mon);}return 0;
}
说来都是缘。就在昨天下午,看了看翁恺老师的C语言进阶课,关于浮点数的知识。
这又给了我新的想法。
上课笔记
浮点运算的精度a = 1.234f 若只写1.234 ,则默认double,只有自己加上标注f/F,才为float。案例a = 1.234fb = 1.123fc = a+b;if(c==2.357) printf----实际上,判断发现c!=2.357.因为浮点数是有误差的。
可能真正的值是2.3579999321【可见,在一些题目,或日常生活中,比u人银行存钱。就不能有浮点数表达。因为他会在暗中对误差进行累计。造成糟糕的结果。那么怎么处理呢?】
【可以先在计算时,把他们化成整型。比如算1.23元时,可以先写成123分】
情况已经很明朗了。我就陷入了浮点误差累计的深渊。
刚才按上面思路改了下。成功了,比原来也简单了。
改动:1.删除了浮点去位操作 2.结构体里的mon用int定义 3.每次累加时,直接加的分(话说题目本就给的分,是在暗示我?)
4.排序时也用的int的mon,只在最后输出时,才 printf("%d %.2lf\n",money[i].id, (double)money[i].mon / 100 );
很高兴,这下全弄明白了。
PTA题目:7-9 抢红包 (25分)相关推荐
- L2-009 抢红包 (25 分)(C语言)(排序)
题目 L2-009 抢红包 (25 分) 没有人没抢过红包吧-- 这里给出N个人之间互相发红包.抢红包的记录,请你统计一下他们抢红包的收获. 输入格式: 输入第一行给出一个正整数N(≤10 4 ),即 ...
- PTA秀恩爱分得快 (25分)
PTA秀恩爱分得快 (25分) 古人云:秀恩爱,分得快. 互联网上每天都有大量人发布大量照片,我们通过分析这些照片,可以分析人与人之间的亲密度.如果一张照片上出现了 K 个人,这些人两两间的亲密度就被 ...
- C语言 7-7 抢红包 (25分)
7-7 抢红包 (25分 题目 代码块 题目 没有人没抢过红包吧-- 这里给出N个人之间互相发红包.抢红包的记录,请你统计一下他们抢红包的收获. 输入格式: 输入第一行给出一个正整数N(≤104), ...
- 【CCCC】L2-009 抢红包 (25分),,间接排序,比较double大小
problem L2-009 抢红包 (25分) 没有人没抢过红包吧-- 这里给出N个人之间互相发红包.抢红包的记录,请你统计一下他们抢红包的收获. 输入格式: 输入第一行给出一个正整数N(≤10 ...
- 题目:L2-031 深入虎穴 (25 分)
题目:题目详情 - L2-031 深入虎穴 (25 分) (pintia.cn) 大意 已知情报藏在一个地下迷宫里,迷宫只有一个入口,里面有很多条通路,每条路通向一扇门.每一扇门背后或者是一个房间,或 ...
- 7-4 抢红包 (25分)
7-4 抢红包 (25分) 没有人没抢过红包吧-- 这里给出N个人之间互相发红包.抢红包的记录,请你统计一下他们抢红包的收获. 输入格式: 输入第一行给出一个正整数N(≤104),即参与发红包和 ...
- PTA 03-树1 树的同构 (25分)
题目地址 https://pta.patest.cn/pta/test/15/exam/4/question/711 5-3 树的同构 (25分) 给定两棵树T1和T2.如果T1可以通过若干次左右 ...
- PTA 哈利·波特的考试 (25分)
哈利·波特的考试 (25分) 题目链接 问题描述: 哈利·波特要考试了,他需要你的帮助.这门课学的是用魔咒将一种动物变成另一种动物的本事.例如将猫变成老鼠的魔咒是haha,将老鼠变成鱼的魔咒是hehe ...
- PTA 7-3 插入排序还是归并排序 (25分)
c++sort函数和equal函数的应用 一. sort函数 sort函数包含在头文件为#include的c++标准库中,调用标准库里的排序方法可以实现对数据的排序. sort(first,last, ...
最新文章
- 数据科学家最常用的十种算法
- 分布式开放消息系统(RocketMQ)的原理与实践
- boost::math::inverse_chi_squared用法的测试程序
- C++基础知识总结(一)
- 第6章 数据库索引优化
- cent6.8 nginx php,CentOS 6.8 安装Nginx
- 【BZOJ1412】【codevs2351】狼和羊的故事,最小割
- GridView的RowCommand事件中取得行索引 技巧
- oracle 重设基线,Oracle SQL执行计划基线总结(SQL Plan Baseline)
- 7.携程架构实践 --- IaaS & PaaS
- 威纶通触摸屏可以解密吗_【实例】西门子PLC变频器和触摸屏综合应用
- python怎么设置背景音乐_怎么设置背景音乐?
- 自有项目Iframe嵌入ThingJS物联网可视化项目代码解析
- 金蝶——“免、抵、退”税操作说明及帐务处理
- 张亚勤退休百度:一个耐人寻味的微笑
- OpenCV中Rect的一些神奇用法
- Python画四张子图-导入数据
- PO模式项目实战思路分析
- 信用评分卡Credit Scorecards (1-7)
- 基于matlab的RS编译码仿真,从底层原理分析RS编译码的实现过程
热门文章
- 云时代的应用性能管理(APM)
- ios 代码例子 卷边的翻书效果
- 计算机制图的特点和原理,计算机地图制图原理、特点及发展趋势
- dvd在线租赁问题 matlab,DVD在线租赁服务管理模型
- 识别连笔字的软件_在线手写文字识别软件快速代抄
- 在64位的Linux系统使用gcc的-m32选项编译32位的程序得到了多余的代码(多余指令call和add)、有多余的.text.__x86.get_pc_thunk.ax
- 止血、回血 苏宁易购正在复苏路上
- 保弘实业|大学生理财必须做到这四点
- QQ返利当当特惠活动(10.26~11.4)
- [扫盲教程]——Mac 新手最容易犯的几项错误