整体思路是先读入数据,再将其进行排序,最后遍历进行配对输出。几个细节:
1.结构体中
struct records {
char name[25];
int time[4];//month,day,hour,minute
int state;//1 for online 0 for offline
}rec[1010];
用一个int型的state,1/0代表online和offline
2.读取数据时,用getchar吸收掉空格
3.配对
temp代表上一个记录,rec[i]代表当前记录
i)当temp.name与rec[i].name不相同时,代表开始遍历另一个人的记录了,此时输出上一个人的总费用,并重置sum,temp指向当前记录,开始下一轮循环
ii)否则是同一个人记录,检查state,只有符合temp.state==1&&rec[i].state == 0时,才代表配对成功
注意:首次配对成功,输出一个名字 和 月份
计算这对记录所产生的费用fare,累加到sum。注意:不要忘记清零fare。
temp指向当前记录,开始下一轮循环
4.在输出某人的sum时,若sum为0,代表此人没有有效配对记录
5.因为上面的逻辑,当有1个以上的人拥有有效配对记录时,最后一个人的sum将不会被输出,需要在循环外面补上。
7.费用计算pair_fare():
采用类似日期间隔计算的方式,加1遍历。参考:Codeup1928 日期差值
注意:fare最后的计算要由美分转化为美元。1美元=100美分
AC代码:
//1016 Phone Bills (25分) https://pintia.cn/problem-sets/994805342720868352/problems/994805493648703488
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
struct records {
char name[25];
int time[4];//month,day,hour,minute
int state;//1 for online 0 for offline
}rec[1010];
bool cmp(records r1, records r2)//先排序然后再配对
{
if (strcmp(r1.name, r2.name) != 0) return strcmp(r1.name, r2.name) < 0;
else if (r1.time[0] != r2.time[0]) return r1.time[0] < r2.time[0];
else if (r1.time[1] != r2.time[1]) return r1.time[1] < r2.time[1];
else if (r1.time[2] != r2.time[2]) return r1.time[2] < r2.time[2];
else if (r1.time[3] != r2.time[3]) return r1.time[3] < r2.time[3];
}
void pair_fare(records on, records off, double* fare, int* rate)
{
int d1 = on.time[1];
int h1 = on.time[2];
int m1 = on.time[3];
int d2 = off.time[1];
int h2 = off.time[2];
int m2 = off.time[3];
int min = 0;
while (d1 < d2 || h1 < h2 || m1 < m2)
{
m1++;
*fare += rate[h1];
min++;
if (m1 > 59)
{
h1++;
m1 = 0;
if (h1 > 23) {
d1++;
h1 = 0;
}
}
}
*fare /= 100;//1美元=100美分
printf("%02d:%02d:%02d %02d:%02d:%02d %d $%.2lf\n", on.time[1], on.time[2], on.time[3], off.time[1], off.time[2], off.time[3], min, *fare);
}
int main()
{
int rate[24] = { 0 };
for (int i = 0; i < 24; i++) {
scanf("%d", rate + i);
}
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++) {
scanf("%s %d:%d:%d:%d", rec[i].name, rec[i].time, rec[i].time + 1, rec[i].time + 2, rec[i].time + 3);
char str[10] = { 0 };
getchar();//吸收掉空格
scanf("%s", str);
if (strcmp(str, "on-line") == 0) rec[i].state = 1;
else rec[i].state = 0;
}
sort(rec, rec + n, cmp);//排序
records temp;//上一条记录
bool change = true;
temp = rec[0];
double sum, fare;//每个人的总费用和每个配对的费用
sum = fare = 0;
for (int i = 1; i < n; i++) {
if (strcmp(rec[i].name, temp.name) != 0) {//另外一个人开始配对
change = true;
if (sum)
printf("Total amount: $%.2lf\n", sum);
sum = 0;
temp = rec[i];
continue;
}
if (temp.state==1&&rec[i].state == 0) {//配对成功
if (change) {//首次配对将输出名字 和 月份
printf("%s %02d\n", temp.name, temp.time[0]);
change = false;
}
pair_fare(temp, rec[i], &fare, rate);
sum += fare;
//fare忘记清零
fare = 0;
}
temp = rec[i];
}
if (sum)
printf("Total amount: $%.2lf", sum);
return 0;
}
来源:CSDN
作者:tangobravo
链接:https://blog.csdn.net/tangobravo/article/details/104108811