PAT甲级真题 1016 Phone Bills

一、题目
在这里插入图片描述
在这里插入图片描述
二、思路
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排序、设置参照点

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值