PAT甲题题解-1016. Phone Bills (25)-模拟排序
Posted 辰曦~文若
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PAT甲题题解-1016. Phone Bills (25)-模拟排序相关的知识,希望对你有一定的参考价值。
博主欢迎转载,但请给出本文链接,我尊重你,你尊重我,谢谢~
http://www.cnblogs.com/chenxiwenruo/p/6789229.html
特别不喜欢那些随便转载别人的原创文章又不给出链接的
所以不准偷偷复制博主的博客噢~~
给出一天24小时内,每个小时内,每分钟的通话费用
给出n个记录,on-line表示通话的开始,off-line表示通话的结束
如果on-line/off-line没有对应的另一个,忽略即可
先按人名排序,名称一样的按时间排序,这里时间统一按分钟来算,即一天有24*60分钟,那么01:01:05就是0*24*60+1*60+5
然后找出彼此配对的on-line和off-line,存入phone数组
然后接下来就是求出每个通话时间的费用即可
(主要是如何计算出费用比较细节麻烦一点,推荐做一下)
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #define ONLINE 0 #define OFFLINE 1 using namespace std; const int maxn=1000+5; const int DAYMINUTE=24*60; const int HOURMINUTE=60; int toll[24]; int n; struct Record{ char name[25]; int time; int month; int day; int hour; int minute; int mark; bool operator<(const Record tmp)const{ if(strcmp(name,tmp.name)==0) return time<tmp.time; else if(strcmp(name,tmp.name)<0) return true; else return false; } }record[maxn]; struct Phone{ char name[25]; int month; int d1,h1,m1; int d2,h2,m2; int time1,time2; }phone[maxn]; int cnt=0; /** 求出第i个配对的通话时间费用 */ int cal(int i){ int sum=0; int start=phone[i].time1; //起始时间 int ends=phone[i].time2; //结束时间 int tmp=0; //统计每个小时的时间段内,通话的分钟 int idx; //对应时间段toll的索引 for(int t=start;t<=ends;t++){ if(t%60==0){ if(t%DAYMINUTE==0) idx=(DAYMINUTE-1)/60; //如果模为0,就应该是DAYMINUTE else idx=(t%DAYMINUTE-1)/60; //因为可能会有连续通话了好几天,所以得取模一下 sum+=tmp*toll[idx]; //通话的分钟*该时间段的费用 tmp=1; //为了方便起见,像01:06:00这种整时的,算作下一小时的 } else tmp++; } if(tmp){ //比如说1:08:03,由于1:08:00的时候算作8-9之间的,实际上统计的tmp=4,所以要-1 sum+=(tmp-1)*toll[(ends%DAYMINUTE)/60]; } return sum; } int main() { char word[10]; for(int i=0;i<24;i++) scanf("%d",&toll[i]); scanf("%d",&n); for(int i=0;i<n;i++){ scanf("%s %d:%d:%d:%d %s",record[i].name,&record[i].month,&record[i].day,&record[i].hour,&record[i].minute,word); record[i].time=(record[i].day-1)*DAYMINUTE+record[i].hour*HOURMINUTE+record[i].minute; if(word[1]==\'n\') record[i].mark=ONLINE; else record[i].mark=OFFLINE; } sort(record,record+n); int last=-1; //之前最近的一个on-line的索引 //找出配对的on-line和off-line,存入phone数组,方便后序处理 for(int i=0;i<n;i++){ if(record[i].mark==ONLINE){ last=i; } if(record[i].mark==OFFLINE && last!=-1){ if(strcmp(record[i].name,record[last].name)==0){ strcpy(phone[cnt].name,record[i].name); phone[cnt].month=record[i].month; phone[cnt].d1=record[last].day; phone[cnt].h1=record[last].hour; phone[cnt].m1=record[last].minute; phone[cnt].time1=record[last].time; phone[cnt].d2=record[i].day; phone[cnt].h2=record[i].hour; phone[cnt].m2=record[i].minute; phone[cnt].time2=record[i].time; cnt++; last=-1; } } } int tot=0,sum=0; for(int i=0;i<cnt;i++){ if(i==0){ printf("%s %02d\\n",phone[i].name,phone[i].month); sum=cal(i); tot+=sum; int len=phone[i].time2-phone[i].time1; double cost=sum*1.0/100; printf("%02d:%02d:%02d %02d:%02d:%02d %d $%.2lf\\n",phone[i].d1,phone[i].h1,phone[i].m1,phone[i].d2,phone[i].h2,phone[i].m2,len,sum*1.0/100); } else{ if(strcmp(phone[i].name,phone[i-1].name)!=0){ printf("Total amount: $%.2lf\\n",tot*1.0/100); printf("%s %02d\\n",phone[i].name,phone[i].month); tot=0; } sum=cal(i); tot+=sum; int len=phone[i].time2-phone[i].time1; int cost=sum*1.0/100; printf("%02d:%02d:%02d %02d:%02d:%02d %d $%.2lf\\n",phone[i].d1,phone[i].h1,phone[i].m1,phone[i].d2,phone[i].h2,phone[i].m2,len,sum*1.0/100); } } if(tot){ printf("Total amount: $%.2lf\\n",tot*1.0/100); } return 0; }
以上是关于PAT甲题题解-1016. Phone Bills (25)-模拟排序的主要内容,如果未能解决你的问题,请参考以下文章