一、题目
二、思路
1、先将所给数据按姓名、时间进行排序,即这样⬇
排好序后,上下相邻的on和off即为配对记录;
🔺C语言中调用qsort对结构体进行排序:
1、记住包含头文件<stdlib.h>
2、示例:qsort(data, n, sizeof(record), cmp);
,第一个参数为要排序的数组名;第二个参数为数组中元素个数;第三个参数为数组的数据类型大小,即每个元素的大小;第四个参数为排序依据,即函数名;
2、计算时间
这里包括跨天打电话的记录,我的初步想法是分类处理:跨天否、跨小时否,代码段如下:
float remnantmin(int i) {//计算分钟零头
float price = 0.0;
price = (60 - data[i].minute) * toll[data[i].hour] + data[i + 1].minute * toll[data[i + 1].hour];
return price;
}
float pricecompute(int i){//i为该条记录的下标
int h = 0, d = 0;
float price = 0.0;
if (data[i].day == data[i + 1].day) {//没跨天时
if (data[i].hour == data[i + 1].hour) {//没跨小时:
price = (data[i + 1].minute - data[i].minute) * toll[data[i].hour];//只计算分钟
}
else {
price = remnantmin(i);//计算分钟零头
for (h = data[i].hour + 1; h < data[i + 1].hour; h++)//计算小时
price += 60 * toll[h];
}
}
else {//跨天:
price = remnantmin(i);//计算分钟零头
for (h = data[i].hour + 1; h < 24; h++)//计算on-line这天的通话小时
price += 60 * toll[h];
for (h = 0; h < data[i + 1].hour; h++)//计算off-line这天的通话小时
price += 60 * toll[h];
price += (data[i + 1].day - data[i].day - 1) * toll[24]*60;//计算跨过的天数的费用
}
return price / 100.0;
}
借鉴柳神的简单做法:
设定参照点01:00:00,即1号的0点0分。分别计算on-line、off-line相对于参考点所花费用,再做减法即可。(值得学习)
🔺坑点:姓名不超过20个字符,应预留的数组大小为21,为结束符’\0’留一个,否则只能过第一个测试点,坑,记住。
三、代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char name[21];
int month, day, hour, minute, time, status;
}record;
record data[1000];
int toll[25];
int cmp(const void *a, const void *b) {//重要!!
record* tmpa = (record*)a;
record* tmpb = (record*)b;
if (strcmp(tmpa->name, tmpb->name)!=0)
return strcmp(tmpa->name, tmpb->name);
else
return tmpa->time - tmpb->time;
}
float pricecompute(int i) {
float price = 0.0;
price = data[i].minute * toll[data[i].hour];
for (int h = 0; h < data[i].hour; h++)
price += 60 * toll[h];
price += (data[i].day - 1) * 60 * toll[24];
return price / 100.0;
/* 分类处理
int h = 0, d = 0;
float price = 0.0;
if (data[i].day == data[i + 1].day) {
if (data[i].hour == data[i + 1].hour) {
price = (data[i + 1].minute - data[i].minute) * toll[data[i].hour];
}
else {
price = remnantmin(i);
for (h = data[i].hour + 1; h < data[i + 1].hour; h++)
price += 60 * toll[h];
}
}
else {
price = remnantmin(i);
for (h = data[i].hour + 1; h < 24; h++)
price += 60 * toll[h];
for (h = 0; h < data[i + 1].hour; h++)
price += 60 * toll[h];
price += (data[i + 1].day - data[i].day - 1) * toll[24]*60;
}
return price / 100.0;
remnant:
float remnantmin(int i) {
float price = 0.0;
price = (60 - data[i].minute) * toll[data[i].hour] + data[i + 1].minute * toll[data[i + 1].hour];
return price;
}
*/
}
void output(int s,int e) {
int num = e - s + 1, i,f=0;
float sum=0,price=0.0;
i = 0;
if (num <= 1)
return;
while (i < num ) {
if (data[s + i].status == 1 && data[s + i + 1].status == 0) {
f++;
if(f==1)
printf("%s %02d\n", data[s].name, data[s].month);
price = pricecompute(s + i + 1) - pricecompute(s + i);
printf("%02d:%02d:%02d %02d:%02d:%02d %d $%.02f\n", data[s + i].day, data[s + i].hour, data[s + i].minute, data[s + i+1].day, data[s + i+1].hour, data[s + i+1].minute, data[s + i + 1].time - data[s + i].time, price);
sum += price;
i += 2;
}
else
i++;
if (s+i >= e)
break;
}
if (f!=0)
printf("Total amount: $%.02f\n", sum);
return;
}
int main() {
int n, i,start,end;
char stat[10] = { 0 };
for (i = 0; i < 24; i++) {
scanf("%d", &toll[i]);
toll[24] += toll[i];
}
scanf("%d", &n);
for (i = 0; i < n; i++) {
scanf("%s %d:%d:%d:%d %s", data[i].name, &data[i].month, &data[i].day, &data[i].hour, &data[i].minute,stat);
data[i].time = data[i].day*24*60+data[i].hour*60+data[i].minute;
if (strcmp(stat, "on-line") == 0)
data[i].status = 1;
else if (strcmp(stat, "off-line") == 0)
data[i].status = 0;
}
qsort(data, n, sizeof(record), cmp);
start = 0; end = 0;
for (i = 0; i < n;i++) {
if (strcmp(data[i].name, data[i+1].name) != 0) {
end = i;
output(start, end);
start = end + 1;
}
}
return 0;
}
学习对数据的存储方法、调用qsort排序、设置参照点