PAT题解——1016. Phone Bills (25)
来源:互联网 发布:如何删除淘宝精选 编辑:程序博客网 时间:2024/06/14 09:47
[声明]:由于本人在使用《算法笔记》的过程中有部分题解和《算法笔记》上的解法不同,特此作为记录,同时可以提供新的思路供读者参考;
1. 题目链接:https://www.patest.cn/contests/pat-a-practise/1016
2. 解题思路:
① 用结构体存储姓名、月、日、时、分以及状态(0表示off-line,1表示on-line);
②对所有结构体数组内容进行排序,先按照姓名升序,使得相同姓名的排在一起,再按照通话时刻升序;
③对排好序的数组进行从头扫描,找出有效配对:即当前的姓名和下一个姓名相同,当前的状态为1,下一个状态为0;若不是有效配对,继续扫描;
④找到有效配对后,根据判断当前的姓名是否输出从而选择性输出姓名,再依次输出两个时刻,调用lasting函数计算并输出总持续时间,调用fee函数计算并输出对应时间段的费用;并加入total_amount;
⑤若当前姓名与下一个姓名不同,说明当前姓名total_amount已经计算完毕,输出即可;
3.AC代码:
#include<stdio.h>#include<cstring>#include<algorithm>using namespace std;const int maxn=1010;struct r{ char name[25]; int mo,dd,hh,mm; int status; //记录状态on-line或者off-line }re[maxn];bool cmp(r a,r b){ if(strcmp(a.name,b.name)) return strcmp(a.name,b.name)<0; else if(a.dd!=b.dd) return a.dd<b.dd; else if(a.hh!=b.hh) return a.hh<b.hh; else return a.mm<b.mm;}int toll[24]; //用于存储一天中每个小时对应的费用 ,单位cent/min int lasting(int d,int h,int m,int dd,int hh,int mm){ //计算持续时间,d,h,m表示开始的日,时,分;dd,hh,mm表示结束时的日,时,分 int time=0; //记录持续的时间,单位:分 while(d!=dd||h!=hh||m!=mm){ //思路:通过不断将初始的m+1,同时time+1,最终和结束时间完全相同即可 ++m;++time; if(m==60){ m=0; ++h; } if(h==24){ h=0; ++d; } } return time;}double fee(int d,int h,int m,int dd,int hh,int mm){ //计算持续时间内的花费,d,h,m表示开始的日,时,分;dd,hh,mm表示结束时的日,时,分 double f=0; //记录话费 while(d!=dd||h!=hh||m!=mm){ ++m;f+=toll[h]; //加上对应小时的话费 if(m==60){ m=0; ++h; } if(h==24){ h=0; ++d; } } return f/100; //cent单位转换为$ }int main(){ int N; //总记录条数 for(int i=0;i<24;i++) scanf("%d",&toll[i]); //输入24小时对应的话费标准,单位cent/min scanf("%d",&N); char temp[10]; //临时记录"on-line"还是"off-line" for(int i=0;i<N;i++){ scanf("%s %d:%d:%d:%d %s",re[i].name,&re[i].mo,&re[i].dd,&re[i].hh,&re[i].mm,temp); if(!strcmp(temp,"on-line")) re[i].status=1; //若是on-line 则状态变为1,否则为0 else re[i].status=0; } sort(re,re+N,cmp); //总体进行排序,相同名字的排一起并升序,然后按照时间先后排序 char last_name[20]; //暂时不用理解 double total=0; //记录总话费 for(int i=0;i<N;i++){ if(strcmp(re[i].name,re[i+1].name)==0&&re[i].status==1&&re[i+1].status==0){ //有效配对 if(strcmp(re[i].name,last_name)){ //如果同名字的人有1对以上的有效配对 ,第二次不用输出姓名,所以用last_name存储上次输出的姓名 printf("%s %02d\n",re[i].name,re[i].mo); //并判断本次有效配对的姓名和上次的是否相同; strcpy(last_name,re[i].name); } printf("%02d:%02d:%02d",re[i].dd,re[i].hh,re[i].mm); printf(" %02d:%02d:%02d",re[i+1].dd,re[i+1].hh,re[i+1].mm); printf(" %d",lasting(re[i].dd,re[i].hh,re[i].mm,re[i+1].dd,re[i+1].hh,re[i+1].mm)); //调用函数计算持续时间,单位min double temp_fee=fee(re[i].dd,re[i].hh,re[i].mm,re[i+1].dd,re[i+1].hh,re[i+1].mm); //调用函数计算此时间段的费用,单位$ printf(" $%.2f\n",temp_fee); total+=temp_fee; //计算总费用 } if(strcmp(re[i].name,re[i+1].name)&&total){ //下一个名字不同,同时总费用不为0,则输出目前这个人的Total amount printf("Total amount: $%.2f\n",total); total=0; //总费用重新置零,用于下一个人的总费用计算 } }}
阅读全文
0 0
- PAT题解——1016. Phone Bills (25)
- 1016. Phone Bills (25)——PAT (Advanced Level) Practise
- 1016. Phone Bills (25)-PAT
- PAT 1016. Phone Bills (25)
- 【PAT】1016. Phone Bills (25)
- PAT 1016. Phone Bills (25)
- PAT 1016. Phone Bills (25)
- PAT 1016. Phone Bills
- 【PAT】1016. Phone Bills
- PAT 1016. Phone Bills (25) 【15/25】
- 【PAT Advanced Level】1016. Phone Bills (25)
- PAT A 1016. Phone Bills (25)
- PAT (Advanced) 1016. Phone Bills (25)
- 【PAT甲级】1016. Phone Bills (25)
- PAT甲级练习1016. Phone Bills (25)
- 1016. Phone Bills (25) PAT甲级
- PAT甲级1016. Phone Bills (25)
- PAT-A-1016. Phone Bills (25)
- java分布式事务的一种简单处理方法
- javaScript被引入的方式
- 切换Centos的yum源,切换为国内的阿里云源和网易163源
- 每天一个Linux命令-17(awk)
- FAFU OJ 素数环
- PAT题解——1016. Phone Bills (25)
- 2016"百度之星"
- 如何在没有https环境下使用webrtc
- 多校第四场1005(hdu6071)dijkstra
- SpringMVC学习之EL表达式二
- WebRTC中如何设置视频的码流
- Iterator迭代器导致的java.util.NoSuchElementException原因与解决方法
- 利用MATLAB计算SPWM脉冲宽度与并应用STM32输出
- init.ps1 cannot be loaded because running scripts is disabled on this system问题的解决