PAT 1016 Phone Bills (25)

来源:互联网 发布:nba15 16赛季数据 编辑:程序博客网 时间:2024/06/06 07:38

题目说明:

输入: 

24个小时每个时段通话价格 美分/分钟 toll[]

通话记录数N

N行通话记录:名字name 时间date 状态status (on-line表示通电话,off-line表示挂电话)

输出:每个客户的账单,按照客户名字的字典顺序输出,每个客户的多条记录按照时间顺序输出。on-line和off-line配对的才是有效记录。

注意点:若客户没有有效记录,则不打印这个客户的账单。

It is guaranteed that at least one call is well paired in the input. 保证至少有一条有效记录,但不是每个客户都有有效记录。

思路:先排序所有记录,按照姓名-时间升序排列,然后逐个计算每个客户的通话记录和话费。话费计算是先计算出从0时刻到通电话时刻的话费和到挂电话时刻的话费,两部分相减得到本条记录的话费。

代码:

#include<iostream>#include<fstream>#include<algorithm>using namespace std;#define MAXN 1005int toll[30];int N;int countdayprice();struct Record{string name;string date;int month; int day;int hour;int min;string status;}record[MAXN];bool cmp(const Record &a,const Record &b){//以姓名排序,姓名相同以时间排序 if(a.name<b.name)return true;else if(a.name==b.name){if(a.date<b.date)return true;else return false;}elsereturn false;}int counttime(int s,int e){int time;time=record[e].day*60*24+record[e].hour*60+record[e].min-(record[s].day*60*24+record[s].hour*60+record[s].min);return time;}//计算从0到某个时间的总花费 int countprice(int day,int hour,int min){int price=0;for(int i=0;i<hour;i++){price+=toll[i];}price*=60;price+=toll[hour]*min;price+=countdayprice()*day;return price;}//计算每条记录的话费 float countrecordprice(int s,int e){float price;//结束减去开始 price=countprice(record[e].day,record[e].hour,record[e].min)-countprice(record[s].day,record[s].hour,record[s].min);return price/100;}//每天一整天的话费 int countdayprice(){int dayprice=0;for(int i=0;i<24;i++){dayprice+=toll[i];}dayprice*=60;return dayprice;}int main(){#ifdef ONLINE_JUDGE#else ifstream cin("aa.txt");#endiffor(int i=0;i<24;i++){cin>>toll[i];}cin>>N;for(int i=0;i<N;i++){cin>>record[i].name>>record[i].date>>record[i].status;string date=record[i].date;record[i].month=(date[0]-48)*10+(date[1]-48);record[i].day=(date[3]-48)*10+(date[4]-48);record[i].hour=(date[6]-48)*10+(date[7]-48);record[i].min=(date[9]-48)*10+(date[10]-48);}//排序所有记录。sort(record,record+N,cmp);string name="0"; int start;int end;float totalamount=0;bool flagon=false;//on-off配对标记 bool flagname=false;//同一个用户的标记 for(int i=0;i<N;i++){if(name!=record[i].name){if(totalamount>0){//输出总话费 printf("Total amount: $%.2f\n",totalamount);}name=record[i].name;flagon=false;flagname=false;totalamount=0;}if(record[i].status=="on-line"){start=i;flagon=true;}else if(record[i].status=="off-line"){if(flagon){//输出name信息 if(!flagname){flagname=true;cout<<name;//string 用cout printf(" %02d\n",record[i].month);}flagon=false;end=i;//输出一条记录 printf("%02d:%02d:%02d %02d:%02d:%02d ",record[start].day,record[start].hour,record[start].min,record[end].day,record[end].hour,record[end].min);float recordprice=countrecordprice(start,end);printf("%d $%.2f\n",counttime(start,end),recordprice);totalamount+=recordprice; }}//最后一条记录的总话费输出 if(i==N-1&&totalamount>0)printf("Total amount: $%.2f\n",totalamount);}return 0;}

之前在排序记录的过程中出现了一些问题,开始是采用两次sort,先对时间进行排序,再对姓名进行排序,但是结果有时会出错。改了cmp函数用一次sort排序就可以了。后来发现sort是不稳定排序,如果要这样做必须用stable_sort进行稳定排序。

string类型只能用cin,cout,不能用scanf,printf ,若要用printf,只能用printf("%s",str.c_str())。

0 0
原创粉丝点击