题目链接:1016 Phone Bills
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 wordon-line
oroff-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 anoff-line
record. Anyon-line
records that are not paired with anoff-line
record are ignored, as areoff-line
records not paired with anon-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
// 繁琐的模拟题
// 题目大意:电话公司要得到客户的通话费用账单,给定每个时间段的价格(cent/每分钟)和客户的通话记录,得到账单。
// 难点: 对字符串的处理 时间转换 匹配相应时间段单价
// raw word:characters 字符;chronologically 按时间顺序;assume 假设;denoting 表示;toll 收费
#include <iostream>
#include <cstdio>
#include <map>
#include <vector>
#include <algorithm>
using namespace std;
// 繁琐的模拟题
// 题目大意:电话公司求客户的通话费用账单,给定每个时间段的价格(cent/每分钟)和客户的通话记录,得到账单
// 难点: 对字符串的处理 时间转换 匹配相应时间段单价
// 解题思路:用哈希表对应时间段的相应单价,模拟时钟暴力相加
// raw word:characters 字符;chronologically 按时间顺序;assume 假设;denoting 表示;toll 收费
// 信息项比较多则整合在一个结构体中
struct node
{
int t, dd, hh, mm;
string sta;
};
// sort自定义比较方式
bool cmp(const node l, const node r)
{
return l.t < r.t;
}
// 名字对信息数组的映射
map<string, vector<node>> mp;
// 收费价格
int toll[30];
int main()
{
// 读入24个小时时间段分别的收费
for (int i = 0; i < 24; i++)
{
scanf("%d", &toll[i]);
}
int n, mouth;
scanf("%d", &n);
for (int i = 1; i <= n; i++)
{
string name, sta;
char c;
node temp;
cin >> name;
// 使用char c去掉':'字符只得到数字
scanf("%d%c%d%c%d%c%d", &mouth, &c, &temp.dd, &c, &temp.hh, &c, &temp.mm);
cin >> temp.sta;
// 将时间日期转化成一个分钟为单位的整数,以用在后面的哈希表映射
temp.t = temp.dd * 1440 + temp.hh * 60 + temp.mm;
// 加入该名字下的vector
mp[name].push_back(temp);
}
// 因为是存在map中的,则名字已自动按字典序排序
for (auto it = mp.begin(); it != mp.end(); it++)
{
auto v = it->second; // 得到该名下的vector
sort(v.begin(), v.end(), cmp); // 将该vector排序
double res = 0; // res保存这个人总账
for (int i = 0; i < v.size();)
{
// s是每对配对成功的分账
double s(0);
if (i + 1 < v.size() && v[i].sta > v[i + 1].sta)
{
if (!res)
{
cout << it->first;
printf(" %02d\n", mouth);
}
// 模拟时钟的运行,一分钟一分钟的增加
for (int time = v[i].t; time < v[i + 1].t; time++)
{
// 每分钟对应的时间段的费用
s += toll[(time / 60) % 24];
}
printf("%02d:%02d:%02d %02d:%02d:%02d %d $%.2lf\n", v[i].dd, v[i].hh, v[i].mm, v[i + 1].dd, v[i + 1].hh, v[i + 1].mm, v[i + 1].t - v[i].t, s / 100);
res += s;
i += 2;
}
else
i++;
}
if (res)
{
printf("Total amount: $%.2lf\n", res / 100);
}
}
return 0;
}