[PAT解题报告] Phone Bills
计算电话费,可以也算做模拟题吧。给定每天24小时内每分钟的通话费用,还有一系列打电话与挂电话的时间(月日时分)——题目说了所有的日期都在同一个月内,所有月份就是吓唬人的。输出格式有点麻烦,对每个人输出每次通话的起止时间和费用,再输出总时间和总费用。注意有些打电话和挂电话不配对,需要忽略……
分析:本题就是复杂的排序,优先按照人名排序,再按照时间排序,这样同一个人的记录在一起了。
对于同一个人我们忽略不在线的找到目前为止第一个没处理的在线时间。
然后忽略它之后在线的找到第一个没处理的不在线的时间(如果有),这两个时间时配对的,中间被忽略那些就不处理了,再继续处理后面的同样找到第一个没处理的在线时间和第一个没处理的不在线时间……如此循环下去。
对于时间,我们开始可以转化成一个整数,因为月份没有用,只考虑日、时、分,我们用管用办法把日* 1440 + 时 * 60 +
分就可以了。
计算费用也很麻烦,我们先把两个日期转换到同一天上去(注意如果不在同一天,较早的日期时和分要变成0),
再把两个日期转换到同一小时内(同理,不在同一小时,较早的先要变成0)
再算分钟,具体算分钟也要加上不同小时内每分钟的具体费用。
这个还是有点麻烦的,详细地请看cal这个函数。
代码:
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
using namespace std;
struct node {
char name[22];
int month;
int day;
int hh;
int mm;
bool online;
};
node p[1024];
int a[24];
bool cmp(const node &a,const node &b) {
int t = strcmp(a.name, b.name);
if (t) {
return (t < 0);
}
return (a.day * 1440 + a.hh * 60 + a.mm) < (b.day * 1440 + b.hh * 60 + b.mm);
}
int cal(int d1,int hh1,int mm1, int d2,int hh2,int mm2) {
int time = 0, pay = 0;
for (; d1 < d2; ++d1) {
time += (60 - mm1);
pay += (60 - mm1) * a[hh1++];
for (mm1 = 0; hh1 < 24; ++hh1){
pay += 60 * a[hh1];
time += 60;
}
hh1 = 0;
}
for (; hh1 < hh2; ++hh1) {
time += (60 - mm1);
pay += (60 - mm1) * a[hh1];
mm1 = 0;
}
time += (mm2 - mm1);
pay += (mm2 - mm1) * a[hh1];
printf("%d $%.2lf\n",time, pay / 100.);
return pay;
}
int main() {
for (int i = 0; i < 24; ++i) {
scanf("%d", a + i);
}
int n;
scanf("%d",&n);
for (int i = 0; i < n; ++i) {
char temp[10];
scanf("%s%d:%d:%d:%d%s",p[i].name, &p[i].month, &p[i].day, &p[i].hh, &p[i].mm, temp);
p[i].online = (temp[1] == 'n');
}
sort(p, p + n, cmp);
for (int i = 0;i < n;) {
int total = 0;
bool have = false;
for (int j = i; i < n; ++i) {
for (; (i < n) && (!strcmp(p[i].name, p[j].name)) && (!p[i].online); ++i)
;
if ((i >= n) || strcmp(p[i].name, p[j].name)) {
break;
}
for (; (i < n) && (!strcmp(p[i].name, p[j].name)) && (p[i].online); ++i)
;
if ((i >= n) || strcmp(p[i].name, p[j].name)) {
break;
}
// i - 1, i
if (!have) {
have = true;
printf("%s %02d\n",p[i].name,p[i].month);
}
printf("%02d:%02d:%02d %02d:%02d:%02d ",p[i - 1].day,p[i - 1].hh, p[i - 1].mm, p[i].day, p[i].hh, p[i].mm);
total += cal(p[i - 1].day,p[i - 1].hh, p[i - 1].mm, p[i].day, p[i].hh, p[i].mm);
}
if (have) {
printf("Total amount: $%.2lf\n",total / 100.);
}
}
return 0;
}
原题链接: http://www.patest.cn/contests/pat-a-practise/1016
查看10道真题和解析