A1016 Phone Bills
摘要
Title: A1016 Phone Bills
Tag: 字符串、sprintf
Memory Limit: 64 MB
Time Limit: 1000 ms
Powered by:NEFU AB-IN
A1016 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. -
思路
大模拟,部分见代码注释
整体思路:- 先处理这一个月,到达的每一分钟花费的前缀和,这样方便O(1)查询
- 读入数据,每个人的record按时间排序,只有online和offline前后连接的两个record才有效
注:
- sprintf 格式化输入字符数组,如
sprintf(format_time, "%02d:%02d:%02d", day, hour, minute);
- char[], char* 转换为string,直接赋值即可,如
char[] a; string x = a
-
代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95/*
* @Author: NEFU AB-IN
* @Date: 2023-01-04 10:54:05
* @FilePath: \GPLT\A1016\A1016.cpp
* @LastEditTime: 2023-01-04 11:17:33
*/
using namespace std;
const int N = 1010, M = 31 * 1440 + 10;
int n;
int cost[24];
double sum[M]; // 存储一个月内所有分钟数的前缀和
struct records
{
int minutes; // 把时间转换为分钟
string state; // on-line or off-line
string format_time; // 格式化时间
bool operator<(const records &t) const
{
return minutes < t.minutes;
}
};
map<string, vector<records>> persons;
int main()
{
for (int i = 0; i < 24; i++)
cin >> cost[i];
// 计算一个月内所有分钟数对应的钱数
for (int i = 0; i < M; i++)
sum[i] = sum[i - 1] + cost[(i - 1) % 1440 / 60] / 100.0; // 减1,算前一个时刻所在分段
cin >> n;
// 读入数据
char name[50], state[10], format_time[20];
int month, day, hour, minute;
for (int i = 0; i < n; i++)
{
scanf("%s %d:%d:%d:%d %s", name, &month, &day, &hour, &minute, state);
int minutes = day * 1440 + hour * 60 + minute;
sprintf(format_time, "%02d:%02d:%02d", day, hour, minute); // 格式化字符串
persons[name].push_back({minutes, state, format_time});
}
for (auto &person : persons)
{
auto name = person.first;
auto record = person.second;
sort(record.begin(), record.end());
// 然后开始找,一前一后是on和off对应的计算时间和话费
double total_money = 0; // 总的钱数
double each_money = 0;
for (int i = 0; i + 1 < record.size(); i++)
{
auto a = record[i], b = record[i + 1];
if (a.state == "on-line" && b.state == "off-line")
{
// 钱为0时,输出这个人名和月份
if (!total_money)
printf("%s %02d\n", name.c_str(), month); // c_str()用来转成字符串
cout << a.format_time << ' ' << b.format_time;
each_money = sum[b.minutes] - sum[a.minutes]; // 不算a的钱
printf(" %d $%.2lf\n", b.minutes - a.minutes, each_money);
total_money += each_money;
}
}
if (total_money)
printf("Total amount: $%.2lf\n", total_money);
}
return 0;
}