【PAT】A1016. Phone Bills(sort)
@(PAT)
链接:https://www.patest.cn/contests/pat-a-practise/1016
题意:
输入每个小时的电话费的rate,然后根据给出的记录,计算每个人的话费并打印。记录由不同的时间以及对应的上线和下线组成,只有临近的上线和下线匹配,才算是有效的记录。
需要注意的地方是:
1. 每个小时的电话费rate是不同的,要特别处理。
2. 只有临近匹配的上线和下线才算是有效的记录。
3. 结果输出按每个人ID的字典序降序排序,输出的有效记录按时间升序排序。
思路:
1. 用struct来存储每个记录,放入vector中,然后sort。
2. 匹配有效记录,放入一个vector中。
3. 处理每个有效记录,计算它们的费用和时间,重点是计算费用函数的编写。具体见下方代码。
My AC code:
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
vector<int> rate;
struct Record
{
string name;
int month;
int day;
int hour;
int minute;
// true for on, false for off
bool on_off_line;
Record(string n, int mo, int d, int h, int mi, bool on_off) {
name = n;
month = mo;
day = d;
hour = h;
minute = mi;
on_off_line = on_off;
}
void printTime() {
printf("%02d:%02d:%02d ", this->day, this->hour, this->minute);
}
};
bool cmp(Record r1, Record r2) {
if (r1.name != r2.name) return r1.name < r2.name;
if (r1.month != r2.month) return r1.month < r2.month;
if (r1.day != r2.day) return r1.day < r2.day;
if (r1.hour != r2.hour) return r1.hour < r2.hour;
if (r1.minute != r2.minute) return r1.minute < r2.minute;
}
float calculateCharge(Record r1, Record r2) {
int min1 = r1.day * 24 * 60 + r1.hour * 60 + r1.minute;
int min2 = r2.day * 24 * 60 + r2.hour * 60 + r2.minute;
printf("%d ", min2 - min1);
int day = r1.day;
int charge= 0;
if (r2.day == r1.day) {
if (r2.hour == r1.hour) {
charge = (r2.minute - r1.minute)* rate[r1.hour];
}
else {
for (int i = r1.hour; i <= r2.hour; i++) {
if (i == r1.hour) {
charge += (60 - r1.minute)* rate[i];
}
else if (i == r2.hour) {
charge += r2.minute* rate[i];
}
else {
charge += 60 * rate[i];
}
}
}
}
else {
for (int i = r1.day; i <= r2.day; i++) {
if (i == r1.day) {
for (int j = r1.hour; j <= 23; j++) {
if (j == r1.hour) {
charge += (60 - r1.minute)* rate[j];
}
else {
charge += 60 * rate[j];
}
}
}
else if (i== r2.day) {
for (int j = 0; j <= r2.hour; j++) {
if (j == r2.hour) {
charge += r2.minute* rate[j];
}
else {
charge += 60 * rate[j];
}
}
}
else {
for (int j = 0; j < 24; j++) {
charge += 60 * rate[j];
}
}
}
}
float c = (float)charge / 100;
printf("$%.2f\n", c);
return c;
}
int main() {
// vector<int> rate;
for (int i = 0; i < 24; i++) {
int rtemp;
scanf("%d", &rtemp);
rate.push_back(rtemp);
}
int n;
vector<Record> records;
scanf("%d", &n);
while (n--) {
string name, time, line;
cin >> name >> time >> line;
int month = (time[0] - '0') * 10 + time[1] - '0';
int day= (time[3] - '0') * 10 + time[4] - '0';
int hour= (time[6] - '0') * 10 + time[7] - '0';
int min= (time[9] - '0') * 10 + time[10] - '0';
bool on_or_off;
if (line == "on-line") {
on_or_off = 1;
}
else {
on_or_off = 0;
}
Record re(name, month, day, hour, min, on_or_off);
records.push_back(re);
}
sort(records.begin(), records.end(), cmp);
vector<Record> rec_used;
for (int i = 1; i < records.size(); i++) {
if (records[i].name== records[i- 1].name&& records[i].on_off_line == 0 && records[i - 1].on_off_line == 1) {
rec_used.push_back(records[i- 1]);
rec_used.push_back(records[i]);
}
}
vector<int> index;
index.push_back(0);
for (int i = 1; i < rec_used.size(); i++) {
if (rec_used[i].name != rec_used[i - 1].name) {
index.push_back(i);
}
}
index.push_back(rec_used.size());
int user_num = index.size()- 1;
for (int i = 0; i < user_num; i++) {
cout << rec_used[index[i]].name << " ";
printf("%02d\n", rec_used[index[i]].month);
int begin = index[i];
int end = index[i + 1]- 1;
float total_charge = 0.0;
for (int j = begin; j <= end; j++) {
rec_used[j].printTime();
if (j % 2 == 1) {
total_charge+= calculateCharge(rec_used[j - 1], rec_used[j]);
}
}
printf("Total amount: $%.2f\n", total_charge);
}
return 0;
}