Phone Bills【PAT 1016题】--- 电话账单结算

题目链接:http://pat.zju.edu.cn/contests/pat-practise/1016

以前在POJ上也见过类似的题,当时还不会qsort,菜的一米,遇到大数据还用链表做,还没等把输入处理完成,就已经头大的发麻了,看来我还是有一点进步的。

这道题我开了个record数组,记录所有的账单,第一步先根据字母表顺序将账单排序分类,在此要大大的感谢一把qsort,它可以数组内指定位置和指定长度进行排序,所以我就没有把账单记录分开存到各个客户名下,而是用qsort分割排序,和单独处理单个客户的账单效果一模一样。第二步,根据客户名称作为id,单独对当前处理的客户记录进行时间排序,然后处理,这道题逻辑有点小复杂,和昨天的那个银行排队一样,都属于无关算法而着重逻辑的,到最后的计算时间和费用有点棘手,不过把思路整清楚就OK了。

这道题要注意的陷阱就一点:1.如果客户A的账单记录没有任何一对是合法的,则客户A什么信息都不输出,估计电信局就这样设计的,一年应该可以省不少木材。^_^

  1 #include <stdio.h>  2 #include <stdlib.h>  3 #include <string.h>  4   5 typedef struct  6 {  7     char name[22];//名字  8     int month;//月份  9     int day;//天 10     int hour;//时 11     int minute;//分 12     char tag[10];//on-line or off-line 13 }record; 14  15 int n; 16 record *rd; 17 int rate[24];//费率 18 int count, start;//记录当前处理的这个用户的记录数目,和当前这个用户的第一条记录位置 19 double totalCharge;//该用户该月的费用合计 20  21 double charge(int sday, int shour, int sminute, int eday, int ehour, int eminute)//计算一条有效电话记录的时长和费用,并返回费用 22 { 23     double cost = 0; 24     long time = 0; 25  26     while(sday < eday)//先让天相等 27     { 28         time += (60 - sminute); 29         cost += (60 - sminute) * rate[shour]; 30         sminute = 0; shour ++;//分化成0,时加1 31         time += 60 * (24 - shour); 32         while(shour < 24) 33         { 34             cost += 60 * rate[shour]; 35             shour ++; 36         } 37         shour = 0; sday ++;//时化成0,天加1 38     }//天此时相等,时分为00:00 39     while(shour < ehour)//再让时相等 40     { 41         time += (60 - sminute); 42         cost += (60 - sminute) * rate[shour]; 43         sminute = 0; shour ++; 44     } 45     time += (eminute - sminute); 46     cost += rate[ehour] * (eminute - sminute); 47  48     printf("%ld $%.2lf\n", time, cost / 100); 49  50     return cost / 100; 51 } 52  53 void totalCount()//数出当前要处理的客户的总记录数目 54 { 55     int i; 56     for(i = start + 1; i < n; i ++) 57     { 58         if(strcmp(rd[i].name, rd[i - 1].name) != 0) 59         { 60             break; 61         } 62         else 63         { 64             count ++; 65         } 66     } 67 } 68  69 int comp_name(const void *a, const void *b) 70 { 71     record c = *(record *)a; 72     record d = *(record *)b; 73  74  75     if(strcmp(c.name, d.name) <= 0) return -1; 76     else return 1; 77 } 78  79 int comp_time(const void *a, const void *b) 80 { 81     record c = *(record *)a; 82     record d = *(record *)b; 83  84     if(c.day < d.day) return -1; 85     else if(c.day > d.day) return 1; 86     else 87     { 88         if(c.hour < d.hour) return -1; 89         else if(c.hour > d.hour) return 1; 90         else 91         { 92             if(c.minute < d.minute) return -1; 93             else return 1; 94         } 95     } 96 } 97  98 int main() 99 {100     int i;101     int flag;//1应该出现offline, 0应该出现online102     int onpos;//记录最近有效的on-line记录位置,为了算出charge103     int sign;//0表示该客户名字和月份还没有输出,1表示已输出104     105 106     while(scanf("%d", &rate[0]) != EOF)107     {108         for(i = 1; i < 24; i ++)109         {110             scanf("%d", &rate[i]);111         }112         scanf("%d", &n);113         rd = (record *)malloc(n * sizeof(record));114         for(i = 0; i < n; i ++)115         {116             scanf("\n%s %d:%d:%d:%d %s", rd[i].name, &rd[i].month, &rd[i].day, &rd[i].hour, &rd[i].minute, rd[i].tag);117         }118         qsort(rd, n, sizeof(record), comp_name);//先将记录按字母表顺序分类119         count = 1; start = 0; totalCount(); sign = 0;120         while(start < n)//整个记录表还没处理完121         {122             qsort(rd + start, count, sizeof(record), comp_time);123             flag = 0;124             totalCharge = 0;125             for(i = start; i < start + count; i ++)//处理该客户126             {127                 if(flag == 0)//期待出现online,如果是offline跳过128                 {129                     if(rd[i].tag[1] == 'f')//off-line130                     {131                         continue;132                     }133                     else//on-line134                     {135                         onpos = i;136                         flag = 1;137                     }138                 }139                 else//期待出现offline,如果是online则更新onpos140                 {141                     if(rd[i].tag[1] == 'n')//on-line142                     {143                         onpos = i;144                     }145                     else//off-line146                     {147                         if(sign == 0)148                         {149                             printf("%s %02d\n", rd[start].name, rd[start].month);150                             sign = 1;151                         }152                         printf("%02d:%02d:%02d %02d:%02d:%02d ", rd[onpos].day, rd[onpos].hour, rd[onpos].minute, rd[i].day, rd[i].hour, rd[i].minute);153                         totalCharge += charge(rd[onpos].day, rd[onpos].hour, rd[onpos].minute, rd[i].day, rd[i].hour, rd[i].minute);154                         flag = 0;155                     }156                 }157             }158             if(sign == 1)159             {160                 printf("Total amount: $%.2lf\n", totalCharge);161             }162             start += count; count = 1; totalCount(); sign = 0;163         }164     }165     return 0;166 }

posted on 2012-03-20 15:23 Rafy 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/Rafy/archive/2012/03/20/2408013.html

Phone Bills【PAT 1016题】--- 电话账单结算相关推荐

  1. PAT 1016 Phone Bills (25分) 逻辑较为复杂 sort() + map

    题目 A long-distance telephone company charges its customers by the following rules: Making a long-dis ...

  2. PAT乙级题库踩坑实录

    PAT乙级题库踩坑实录 [截止2021.7.28乙级题库已经全部AC] 题目名称: 1030 完美数列 (25 分) 测试点3踩坑 每次取m后,不用从m后第一个元素开始判断是否大于mp,直接从m后第m ...

  3. 软件测试——电话账单收费

    对电话账单来说,春季和秋季的标准时间与夏时制时间的转换会带来有意思的问题.春季,这种转换发生在(3 月末,4 月初的)星期日凌晨 2:00 时,这时时钟要设置为凌晨 3:00 时.对称的转换通常发生在 ...

  4. pat真题1002 写出这个数C语言解法和java解法

    pat真题1002 写出这个数C语言解法和java解法 读入一个正整数 n,计算其各位数字之和,用汉语拼音写出和的每一位数字. 输入格式: 每个测试输入包含 1 个测试用例,即给出自然数 n 的值.这 ...

  5. PAT刷题之乙级1033 旧键盘打字

    目录 PAT刷题之乙级1033(cpp) 题目描述 输入格式 输出格式 输入样例 输出样例 问题分析 代码实现 运行实现 PAT刷题之乙级1033(cpp) 题目描述 旧键盘上坏了几个键,于是在敲一段 ...

  6. 【PAT】PAT甲级题库所有题解(持续更新中...)

    题解: 本文为导航页,一些希望刷PAT甲级的玩家可以来看看,我会持续更新所有题目的题解(取决于我做到哪儿了(doge)) 题号按照PAT官网给出的标注 题目: 链接 标签 1001 A+B Forma ...

  7. 【PAT乙级题库】全套总结

    我将难度分为三个等级: 简单 中等 难 简单的做一次足以,做再多遍也无任何的意义. 中等的可以多刷几遍 难的多刷几遍 目录 1001 害死人不偿命的(3n+1)猜想[简单] 1002 写出这个数 (2 ...

  8. C语言PAT刷题 - 1020 月饼

    作者的话:若有朋友复制代码去PAT试着运行遇到问题的: 1.可能是格式问题,可以先把从本站复制的代码粘贴到记事本,再把记事本里的代码复制,然后粘贴到PAT的代码区,提交本题回答,应该就可以了: 2.可 ...

  9. C语言PAT刷题 - 1019 数字黑洞

    作者的话:若有朋友复制代码去PAT试着运行遇到问题的: 1.可能是格式问题,可以先把从本站复制的代码粘贴到记事本,再把记事本里的代码复制,然后粘贴到PAT的代码区,提交本题回答,应该就可以了: 2.可 ...

  10. PAT做题过程中的一些方法技巧总结

    1.格式化输出整数 例子: 7766 - 6677 = 1089 9810 - 0189 = 9621 9621 - 1269 = 8352 8532 - 2358 = 6174 printf(&qu ...

最新文章

  1. Vue + Bootstrap|Element UI——模态框被遮罩层遮盖问题解决方案
  2. 维护没有源代码的遗留 Java 项目
  3. 正则表达式matlab,正则表达式中一个word的匹配 @MATLAB - 优秀的Free OS(Linux)版 - 北大未名BBS...
  4. android compress函数,Linux Kernel(Android) 加密算法小结(cipher、compress、digest)
  5. 编程珠玑笔记-第12章习题
  6. 【非功能性测试】软件测试之非功能性测试有哪些?
  7. 2019计算机专业英语国家线,2019英语一国家线多少
  8. Mtk ALPS Led驱动的加载过程
  9. 面向对象设计,ORM,NHIBERNATE杂谈(有感)
  10. rime 简体中文 linux,Rime (简体中文)
  11. King of Fighters 2003 全人物发招表(转)
  12. 使用Minifly打造基于视觉感知的跟踪无人机
  13. 浅谈To B与To C的区别
  14. SVN误删的文件可以恢复
  15. Coinversation Protocol (铸币协议)简版白皮书及网站
  16. 自然数的皮亚诺公理系統
  17. daad转换器实验数据_DAAD留德日记作者:20分钟我拿到了德企总部的实习offer
  18. oracle asru,最佳实践之二:VSP+ORACLE
  19. 员工强烈要求不买社保怎么规避风险 企业不交社保怎样规避风险
  20. Yahoo前端的35条优化军规

热门文章

  1. 处理得怎么样填空词语_武都网络推广软件效果怎么样【易商网络】
  2. 直播程序源码更简单的搭建方法
  3. 恐怖的死亡艺术,稻川淳二为自己办了场VR葬礼
  4. KeyMob--最智能的移动广告聚合平台
  5. 第10章 接口、继承与多态----对象类型的转换
  6. yum快速安装mysql
  7. ×××计算机信息系统安全保护条例
  8. 用css实现了一个精致的纵向导航菜单
  9. PHP文件上传实现的注意点
  10. 【JavaEE】第零章(2020.03.06)模式 表 索引