PAT 1016 Phone Bills
今天给大家分享一道PAT甲级的小题,考察点: 模拟
简单翻译:
先输入24个价格,第i个表示一天中的第i小时打电话是多少美分一分钟
再输入一个N,表示在线电话记录的个数
下面N行数据,每行包括一个电话记录,字段包括:
名字 - 时间(MM:dd:HH:mm) - 状态(on-line / off-line)
给每个有完整通话记录的用户打印自己的账单。格式如下所示:
姓名 月份
开始时间 结束时间 消费金额
…
总消费
思路:
这个题目,真的把真实场景给模拟的透透的,(其实他还做了简化,因为规定说只能在一个月里,如果加上月份,每个月还有28天,29天,30天,31天,会更难搞(我太菜了…))
- 先对得到的数据进行整理和排序,第一关键字是用户名,第二关键字是时间。
- 排序完之后就模拟一下即可,注意一点就是状态的判断,只有先on-line之后在off-line才算完整的一次通话。
- 最后就是计算消费的时候,可以不用模拟,而是直接暴力循环算消费,这样会少很多思考量(我太菜了对不起)。
cpp代码:
#include<bits/stdc++.h>
#define ll long long int
#define vi vector<int>
#define vvi vector<vector<int>>
#define fastio ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
#define INF (1e9)
#define all(x) x.begin(), x.end()
#define len(x) x.size()
#define pb(x) push_back(x)
using namespace std;
struct node {
string name;
int time, type;
}node[1001];
int cost[24];
int totalCost;
void f(int startTime, int endTime) {
ll costs = 0;
ll dayCost = 0;
for (int i = 0; i < 24; i++)
dayCost += cost[i] * 60;
int day1 = startTime / 1440 + 1;
int hour1 = (startTime - 1440 * (day1 - 1)) / 60;
int m1 = startTime - (day1 - 1) * 1440 - hour1 * 60;
printf("%02d:%02d:%02d ", day1, hour1, m1);
int day2 = endTime / 1440 + 1;
int hour2 = (endTime - 1440 * (day2 - 1)) / 60;
int m2 = endTime - (day2 - 1) * 1440 - hour2 * 60;
printf("%02d:%02d:%02d %d $", day2, hour2, m2, endTime - startTime);
for (int i = 0; i < endTime - startTime; i++) {
m1++;
costs += cost[hour1];
if (m1 == 60) {
hour1++;
m1 = 0;
if (hour1 == 24) {
day1++;
hour1 = 0;
}
}
}
printf("%.2lf\n", costs / 100.0);
totalCost += costs;
}
int main() {
//fastio;
totalCost = 0;
for (int i = 0; i < 24; i++) scanf("%d", &cost[i]);
int n;
scanf("%d", &n);
int month;
for (int i = 0; i < n; i++) {
string type;
int day, hour, m;
cin >> node[i].name;
scanf("%d:%d:%d:%d", &month, &day, &hour, &m);
cin >> type;
node[i].time = (day - 1) * 1440 + hour * 60 + m;
node[i].type = (type == "off-line" ? 0 : 1);
}
sort(node, node + n, [&](const struct node& a, const struct node & b)->bool{
if (a.name != b.name) return a.name < b.name;
return a.time < b.time;
});
string name = "";
bool flag = false;
int startTime = -1, endTime = -1;
for (int i = 0; i < n; i++) {
if (node[i].name != name) {
name = node[i].name;
startTime = -1;
endTime = -1;
if (totalCost != 0) {
printf("Total amount: $%.2lf\n", totalCost / 100.0);
totalCost = 0;
}
flag = false;
}
if (node[i].type == 1) {
startTime = node[i].time;
}
if (node[i].type == 0 && startTime != -1) {
endTime = node[i].time;
if (!flag) { cout << name; printf(" %02d\n", month); flag = true;}
f(startTime, endTime);
endTime = -1;
startTime = -1;
}
}
if (totalCost != 0) {
printf("Total amount: $%.2lf\n", totalCost / 100.0);
totalCost = 0;
}
return 0;
}