日常记录:天梯赛练习集L1-043 阅览室

 题目:

日常记录:天梯赛练习集L1-043 阅览室_第1张图片

天梯图书阅览室请你编写一个简单的图书借阅统计程序。当读者借书时,管理员输入书号并按下S键,程序开始计时;当读者还书时,管理员输入书号并按下E键,程序结束计时。书号为不超过1000的正整数。当管理员将0作为书号输入时,表示一天工作结束,你的程序应输出当天的读者借书次数和平均阅读时间。

注意:由于线路偶尔会有故障,可能出现不完整的纪录,即只有S没有E,或者只有E没有S的纪录,系统应能自动忽略这种无效纪录。另外,题目保证书号是书的唯一标识,同一本书在任何时间区间内只可能被一位读者借阅。

输入格式:

输入在第一行给出一个正整数N(≤10),随后给出N天的纪录。每天的纪录由若干次借阅操作组成,每次操作占一行,格式为:

书号([1, 1000]内的整数) 键值SE) 发生时间hh:mm,其中hh是[0,23]内的整数,mm是[0, 59]内整数)

每一天的纪录保证按时间递增的顺序给出。

输出格式:

对每天的纪录,在一行中输出当天的读者借书次数和平均阅读时间(以分钟为单位的精确到个位的整数时间)。

输入样例:

3
1 S 08:10
2 S 08:35
1 E 10:00
2 E 13:16
0 S 17:00
0 S 17:00
3 E 08:10
1 S 08:20
2 S 09:00
1 E 09:20
0 E 17:00

输出样例:

2 196
0 0
1 60

 解答:

题目分析:

  • 需统计每天有效借书次数和平均借阅时间
  • 有效借书为有借有还
  • 书号范围为[1,1000]
  • 书号为0时表示图书馆下班,此时应统计当天数据
  • 需自动忽略不完整记录
  • 计算平均借阅时间时以分钟为单位,且需要四舍五入
  • 计算借阅时间时,只需要将有效借阅时间的小时之差乘以60再加上分钟之差即可

题目理解:

  •  连续多次借书,以最后一次借为准,连续多次还书,以第一次还为准

 操作实现:

  1. 定义BOOK结构体,内含开始结束时的时间hour、min和当前借阅状态state,同时定义N为1010,表示最多有1000本书,多开辟的空间防止数组越界
  2. 定义Time函数,计算一本书有效借阅时长
  3. 定义n表示统计n天借阅情况,即输出n行
  4. 利用for循环循环n次,内定义有效借阅次数count和当天借阅总时长time
  5. 利用while循环实现统计当天所有借阅归还记录,当num为0时表示当天图书馆已下班,退出while循环
  6. 退出while循环后,需计算并输出当日有效借阅次数和平均借阅时长

小贴士:

  • 为防止在读入flag时读入空格键,可以每次输入用scanf读入一整行的数据,规范化输入
  • 计算平均借阅时长时,若count==0,则会出现除零异常,需使用if-else语句输出count==0时的情况
  • 四舍五入算法可以先将整数除法转化为浮点数除法,将结果加上0.5,再强转为整型,从而达到四舍五入的效果

代码实现:

#include 
#include 
using namespace std;

const int N = 1010;	//定义BOOK数组长度

int Time(int bhour, int bmin, int ehour, int emin);	//声明时间统计函数

typedef struct
{
	int hour;	//借阅开始小时
	int min;	//借阅开始分钟
	char state = 'E';	//设置初始状态为归还状态
}BOOK;

int main()
{
	int n; cin >> n;	//n天
	BOOK book[N];	//定义BOOK数组
	for (int i = 0; i < n; i++)	//统计n天内数据
	{
		int num;	//书号
		char flag;	//借阅状态
		int hour, min;	//当前小时和分钟

		int count = 0;	//当天有效借阅次数
		int time = 0;	//当天有效借阅时长
		scanf("%d %c %d:%d", &num, &flag, &hour, &min);	//输入借阅记录
		while (num)	//当num为0时表示下班,退出循环
		{
			if (flag == 'S' && book[num].state == 'E')	//有效借阅
			{
				book[num].hour = hour;	//更新借阅时间
				book[num].min = min;	//更新借阅时间
				book[num].state = flag;	//更新借阅状态
			}
			else if (flag == 'E' && book[num].state == 'S')	//有效归还
			{
				time += Time(book[num].hour, book[num].min, hour, min);	//计算本次借书时长
				count++;	//有效借阅次数加一
				book[num].state = flag;	//更新借阅状态
			}
			else if (flag == 'S' && book[num].state == 'S')	//无效借阅
			{
				book[num].hour = hour;	//更新借阅时间,保留最后一次借阅时间
				book[num].min = min;	//更新借阅时间,保留最后一次借阅时间
			}
			else if (flag == 'E' && book[num].state == 'E');//无效归还,不做处理
			scanf("%d %c %d:%d", &num, &flag, &hour, &min);	//输入下一条借阅记录
		}
		if (count) printf("%d %d\n", count, int(time*1.0 / count + 0.5));	//若count不为0,则计算后输出统计结果
		else printf("0 0\n");	//若count为0,则输出0 0
	}
	return 0;
}

//定义时间统计函数,参数为借阅时的小时和分钟,归还时的小时和分钟
int Time(int bhour, int bmin, int ehour, int emin)
{
	return ((ehour - bhour) * 60 + (emin - bmin));	//返回借阅借阅时长
}

PTA题目地址 

欢迎大家探讨

你可能感兴趣的:(PTA天梯赛练习集,c++,图论,算法,c语言)