这道题有几个关键点
记录匹配
- 按时间排序后,每一个
on-line
记录与同名的最近的off-line
记录匹配
Eachon-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.
之前我们似乎见过这样的题目描述方式嘛:异曲同工的记录匹配方法
结果记录
使用结构体记录匹配成功的通话记录
使用map将用户名映射到相应的编号上
struct node2 {
char name[25];
int cnt;
int start[N];
int end[N];
int bill[N];
int tot_bill;
};
node2 ans[N];
话费计算
我的想法是,设置一个信标按照小时移动
int cal_bill(int s, int t) {
int ans = 0;
int a = 0;
for (int i = 0; ; ++i) {
a += 60;
if (a > s && a <= t) {
ans += (a - s) * toll[i % 24];
s = a;
}
if (a > t) {
ans += (t - s) * toll[i % 24];
break;
}
}
return ans;
}
输出细节
输出时要注意补零,空格
话费要从美分转为美元
AC代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<map>
#include<string>
#include<algorithm>
using namespace std;
const int N = 1010;
map<string, int> myMap;
struct node {
char name[25];
int time;
int flag;
};
node call[N];
int n,month;
int toll[30];
struct node2 {
char name[25];
int cnt;
int start[N];
int end[N];
int bill[N];
int tot_bill;
};
node2 ans[N];
int cmp(const node& A, const node& B) {
return A.time < B.time;
}
int cmp2(const node2& A, const node2& B) {
return strcmp(A.name, B.name) < 0;
}
int changeToFlag(char *s) {
if (s[1] == 'n') return 0;
else return 1;
}
int changeToTime(char* s) {
int d = (s[3] - '0') * 10 + s[4] - '0';
int h = (s[6] - '0') * 10 + s[7] - '0';
int m = (s[9] - '0') * 10 + s[10] - '0';
return d * 24 * 60 + h * 60 + m;
}
int cal_bill(int s, int t) {
int ans = 0;
int a = 0;
for (int i = 0; ; ++i) {
a += 60;
if (a > s && a <= t) {
ans += (a - s) * toll[i % 24];
s = a;
}
if (a > t) {
ans += (t - s) * toll[i % 24];
break;
}
}
return ans;
}
void prt_time(int t) {
int d = t / (24 * 60);
int h = (t % (24 * 60)) / 60;
int m = t % 60;
printf("%02d:%02d:%02d", d, h, m);
}
int main()
{
for (int i = 0; i < 24; ++i) scanf("%d",&toll[i]);
scanf("%d",&n);
for (int i = 1; i <= n; ++i) {
char a[25];
char b[20];
char c[20];
scanf("%s%s%s",&a,&b,&c);
strcpy(call[i].name, a);
call[i].time = changeToTime(b);
call[i].flag = changeToFlag(c);
if (i == 1) month = (b[0] - '0') * 10 + b[1] - '0';
}
sort(call + 1, call + 1 + n, cmp);
int cnt = 0;
for (int i = 1; i < n; ++i) {
if (call[i].flag == 0) {
for (int j = i + 1; j <= n; ++j) {
if (strcmp(call[i].name, call[j].name) == 0) {
//只有可能与遇到的第一个有相同name的记录匹配
if (call[j].flag == 1) {
if (myMap[call[i].name] == 0) {
myMap[call[i].name] = ++cnt;
ans[cnt].cnt = 0;
strcpy(ans[cnt].name, call[i].name);
}
int id = myMap[call[i].name];
ans[id].cnt++;
ans[id].start[ans[id].cnt] = call[i].time;
ans[id].end[ans[id].cnt] = call[j].time;
ans[id].bill[ans[id].cnt] = cal_bill(call[i].time, call[j].time);
ans[id].tot_bill += ans[id].bill[ans[id].cnt];
}
break;
//匹配不上
}
}
}
}
sort(ans + 1, ans + 1 + cnt, cmp2);
for (int i = 1; i <= cnt; ++i) {
printf("%s %02d\n",ans[i].name,month);
for (int j = 1; j <= ans[i].cnt; ++j) {
prt_time(ans[i].start[j]);
printf(" ");
prt_time(ans[i].end[j]);
printf(" %d $%0.2lf\n", ans[i].end[j] - ans[i].start[j],(double)ans[i].bill[j]/100.0);
}
printf("Total amount: $%0.2lf\n", (double)ans[i].tot_bill / 100);
}
return 0;
}