A long-distance telephone company charges its customers by the following rules:

Making a long-distance call costs a certain amount per minute, depending on the time of day when the call is made. When a customer starts connecting a long-distance call, the time will be recorded, and so will be the time when the customer hangs up the phone. Every calendar month, a bill is sent to the customer for each minute called (at a rate determined by the time of day). Your job is to prepare the bills for each month, given a set of phone call records.

Input Specification:

Each input file contains one test case. Each case has two parts: the rate structure, and the phone call records.

The rate structure consists of a line with 24 non-negative integers denoting the toll (cents/minute) from 00:00 - 01:00, the toll from 01:00 - 02:00, and so on for each hour in the day.

The next line contains a positive number N (<= 1000), followed by N lines of records. Each phone call record consists of the name of the customer (string of up to 20 characters without space), the time and date (mm:dd:hh:mm), and the word "on-line" or "off-line".

For each test case, all dates will be within a single month. Each "on-line" record is paired with the chronologically next record for the same customer provided it is an "off-line" record. Any "on-line" records that are not paired with an "off-line" record are ignored, as are "off-line" records not paired with an "on-line" record. It is guaranteed that at least one call is well paired in the input. You may assume that no two records for the same customer have the same time. Times are recorded using a 24-hour clock.

Output Specification:

For each test case, you must print a phone bill for each customer.

Bills must be printed in alphabetical order of customers' names. For each customer, first print in a line the name of the customer and the month of the bill in the format shown by the sample. Then for each time period of a call, print in one line the beginning and ending time and date (dd:hh:mm), the lasting time (in minute) and the charge of the call. The calls must be listed in chronological order. Finally, print the total charge for the month in the format shown by the sample.

Sample Input:

10 10 10 10 10 10 20 20 20 15 15 15 15 15 15 15 20 30 20 15 15 10 10 10
10
CYLL 01:01:06:01 on-line
CYLL 01:28:16:05 off-line
CYJJ 01:01:07:00 off-line
CYLL 01:01:08:03 off-line
CYJJ 01:01:05:59 on-line
aaa 01:01:01:03 on-line
aaa 01:02:00:01 on-line
CYLL 01:28:15:41 on-line
aaa 01:05:02:24 on-line
aaa 01:04:23:59 off-line

Sample Output:

CYJJ 01
01:05:59 01:07:00 61 $12.10
Total amount: $12.10
CYLL 01
01:06:01 01:08:03 122 $24.40
28:15:41 28:16:05 24 $3.85
Total amount: $28.25
aaa 01
02:00:01 04:23:59 4318 $638.80
Total amount: $638.80
 #include<cstdio>
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
typedef struct{
char id[];
int m, dd, hh, mm;
int on_line;
}info;
int N, rates[];
bool cmp(info a, info b){
if(strcmp(a.id, b.id) < )
return true;
else if(strcmp(a.id, b.id) == && a.m < b.m)
return true;
else if(strcmp(a.id, b.id) == && a.m == b.m && a.dd < b.dd)
return true;
else if(strcmp(a.id, b.id) == && a.m == b.m && a.dd == b.dd && a.hh < b.hh)
return true;
else if(strcmp(a.id, b.id) == && a.m == b.m && a.dd == b.dd && a.hh == b.hh && a.mm < b.mm)
return true;
else return false;
}
double counts(info a, info b, int &length){
double sum = ;
length = ;
while(a.dd < b.dd || a.hh < b.hh || a.mm < b.mm){
sum += rates[a.hh];
a.mm++;
length++;
if(a.mm == ){
a.mm = ;
a.hh++;
}
if(a.hh == ){
a.hh = ;
a.dd++;
}
}
return sum;
}
int main(){
info records[];
char id[] = {'\0'}, states[];
for(int i = ; i < ; i++)
scanf("%d", &rates[i]);
scanf("%d", &N);
for(int i = ; i < N; i++){
scanf("%s %d:%d:%d:%d %s", records[i].id, &records[i].m, &records[i].dd, &records[i].hh, &records[i].mm, states);
if(strcmp(states, "on-line") == )
records[i].on_line = ;
else
records[i].on_line = ;
}
sort(records, records + N, cmp);
int prt = , length;
double charge = , temp;
for(int i = ; i < N - ; i++){
if(strcmp(records[i].id, records[i + ].id) == && records[i].on_line == && records[i + ].on_line == ){
if(prt == ){
printf("%s %02d\n", records[i].id, records[i].m);
prt = ;
}
temp = counts(records[i], records[i + ], length) / ;
printf("%02d:%02d:%02d %02d:%02d:%02d %d $%.2f\n", records[i].dd, records[i].hh, records[i].mm, records[i + ].dd, records[i + ].hh, records[i + ].mm, length, temp);
charge += temp;
}else if(strcmp(records[i].id, records[i + ].id) != ){
if(prt == ){
printf("Total amount: $%.2f\n", charge);
}
charge = ;
prt = ;
}
}
if(prt == ){
printf("Total amount: $%.2f", charge);
}
cin >> N;
return ;
}

总结:

1、本题的要求是,对同一个用户,先对无序的记录按照时间排序,只有两条紧邻的且前者为on-line后者为off-line的记录才视作有效记录,对这些有效记录作一些统计,并输出。

2、首先采用struct记录每个时间节点的信息。为了方便后续处理,对这些信息进行排序,相同的人的信息在一起,且同一个人的信息按时间顺序排列。如果是自己写排序算法,则可采用具有稳定性的排序算法进行两次排序,第一次按照时间顺序,第二次按照人名的字典序。如果采用c++自带sort函数,在自定义比较函数cmp时,a与b的大小定义为:如果a的id小于b的id,则a<b, id相等则比较时间,a的时间小于b的时间,则a<b。

3、在计算单次通话时长和通话费用时,可以采用之前的日期计算的套路,从小日期往大日期累加1,过程中不断注意进制。循环进行的条件为 a.dd < b.dd || a.hh < b.hh || a.mm < b.mm, 因为a时间大于等于b时间是 a.dd >= b.dd && a.hh >= b.hh && a.mm >= b.mm。

4、在做这道题的时候还遇到一个问题,在count函数加了一个引用传参时,编译器报错,百思不得其解。网上查了之后才知道std里有count函数模板,与我定义的count有冲突,改掉名字之后成功编译。

5、double变量,输入时为%lf, 输出时为%f。

A1016. Phone Bills的更多相关文章

  1. A1016 Phone Bills (25)(25 分)

    A1016 Phone Bills (25)(25 分) A long-distance telephone company charges its customers by the followin ...

  2. PAT A1016 Phone Bills (25 分)——排序,时序

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

  3. PAT A1016 Phone Bills (25)

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

  4. A1016 Phone Bills (25 分)

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

  5. PAT甲级——A1016 Phone Bills

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

  6. PTA A1016

    A1016 Phone Bills (25 分) 题目内容 A long-distance telephone company charges its customers by the followi ...

  7. PAT_A1016#Phone Bills

    Source: PAT A1016 Phone Bills (25 分) Description: A long-distance telephone company charges its cust ...

  8. PAT题目AC汇总(待补全)

    题目AC汇总 甲级AC PAT A1001 A+B Format (20 分) PAT A1002 A+B for Polynomials(25) PAT A1005 Spell It Right ( ...

  9. 【算法学习记录-排序题】【PAT A1016】Phone Bills

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

随机推荐

  1. Centos7.2下OpenVPN 环境完整部署记录

    关于OpenVPN的有关介绍及为何使用OpenVPN在此就不做赘述了,下面直接记录Centos7.2系统下部署OpenVPN环境的操作过程: 1) 先将本机的yum换成阿里云的yum源 [root@t ...

  2. 索引节点(inode)爆满问题处理

    关于磁盘空间中索引节点爆满的问题还是挺多的,借此跟大家分享几个情况: 情况一 在公司一台配置较低的Linux服务器(内存.硬盘比较小)的/data分区内创建文件时,系统提示磁盘空间不足,用df -h命 ...

  3. better-scroll的参数和方法

    格式:let obj = new BScroll(object,{[option1,],.,.}); 注意,如果在某一个组件内创建了一个BScroll的实例,在组件生命周期结束前要注意调用destro ...

  4. “北航学堂”M2阶段postmortem

    “北航学堂”M2阶段postmortem 设想和目标 1. 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? 这个问题我们在M1阶段的时候就已经探讨的比较明确了,就是 ...

  5. pl/sql破解方法

    转载源:http://blog.csdn.net/oscar999/article/details/2123803 打开注册表在run下输入regedit删除1.HKEY_CURRENT_USER/S ...

  6. Python学习笔记 -- 第六章 文件操作

    I/O编程 在磁盘上读写文件的功能都是由操作系统提供的,现代操作系统不允许普通的程序直接操作磁盘,所以,读写文件就是请求操作系统打开一个文件对象(通常称为文件描述符),然后,通过操作系统提供的接口从这 ...

  7. HanderBar

    对于java开发,涉及到页面展示时,比较主流的有两种解决方案: 1. struts2+vo+el表达式. 这种方式,重点不在于struts2,而是vo和el表达式,其基本思想是:根据页面需要的信息,构 ...

  8. SVN解决冲突

    SVN冲突出现场景 如今是一个团结协作的时代,开发一个系统,往往会多人协作共同完成.版本管理是必不可少的,常用的软件有Git,SVN等.今天说一下,SVN管理版本时,如果出现冲突后,如何快速解决冲突. ...

  9. [福大软工] Z班——Beta现场答辩反馈

    Beta现场答辩 互评反馈 各组对于 麻瓜制造者 的评价与建议 队伍名 评价与建议 *** 功能继续完善,二手市场有闲鱼这条大鱼,要继续体现区域性的优势 *** web端的UI很好看,但安卓和web相 ...

  10. curl用法一例 传递代理用户名密码

    curl -u bb0e1736d66744495b814b942fd04a80:0e11dda88048ed52cc8758caf06dc6b4 https://jinshuju.net/api/v ...