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. iphone忘记锁屏密码却记得appleID密码的不保存数据的刷机办法

    请注意看清题目再看本文,另外一切后果博主不负任何责任.操作实现环境:原装数据线,拔掉sim卡昨天,iPhone6sp忘记密码被锁定,尝试通过找回手机抹除手机功能后,提示需要手机接入互联网才能实现,而我 ...

  2. Html5计算MD5值

    教程: http://www.tuicool.com/articles/InEBNz 组件: https://github.com/satazor/js-spark-md5

  3. 附加题(一)——interesting的抄袭现象

    这次的作业很有意思,是让我们搜索抄袭的同学的个人总结,并让我们列出链接,时间,作者及原因.其实我不是很能理解,抄袭现象是可耻的不受推崇的这是无可厚非,但是为什么要求我们大部分没有抄袭的同学去探究抄袭同 ...

  4. 《Linux内核设计与实现》第十八章读书笔记

    1.内核中的bug 内核中的bug表现得不像用户级程序中那么清晰——因为内核.用户以及硬件之间的交互会很微妙: 从隐藏在源代码中的错误到展现在目击者面前的bug,往往是经历一系列连锁反应的事件才可能触 ...

  5. 20135323符运锦----第七周:Linux内核如何装载和启动一个可执行程序

    可执行程序的装载 一.预处理.编译.链接和目标文件的格式 1.可执行程序是怎么得来的 ①编译器预处理 gcc -E -o XX.cpp XX.c (-m32)// 注:把include的文件包含进来, ...

  6. github学习步骤

    组员1:    王文政      201303011159 作业网址 :https://github.com/1246251747/3/blob/master/jjj.txt 心得: 1.  申请gi ...

  7. SE Springer小组之《Spring音乐播放器》可行性研究报告五、六

    5 可选择的其他系统方案 曾经考虑过制作闹钟系统,但考虑到闹钟系统在电脑应用中极其不实用,所以此方案未通过. 6 投资及效益分析 6.1支出 本软件只用于完成课程学习要求,不用做商用,无基础设备等支出 ...

  8. iOS推送证书生成pem文件(详细步骤)

    1.pem文件概述 pem文件是服务器向苹果服务器做推送时候需要的文件,主要是给php向苹果服务器验证时使用,下面介绍一下pem文件的生成. 2.生成pem文件步骤 1.打开钥匙串,选择需要生成的推送 ...

  9. git学习笔记——廖雪峰git教程

    OK,先附上教程--廖雪峰的官方网站 友情连接:git官网 简介 这里我只想引用他的原文: Linus可以向BitMover公司道个歉,保证以后严格管教弟兄们,嗯,这是不可能的.实际情况是这样的: L ...

  10. Java 编码规范 StandardCharsets.UTF_8 三个方法 toString() name() displayName(),到底用哪个方法更合适?

    想用StandardCharsets.UTF_8 返回"UTF-8"这个字符,测试一下,三个方法toString() name() displayName(),均能返回" ...