题目:
天梯图书阅览室请你编写一个简单的图书借阅统计程序。当读者借书时,管理员输入书号并按下S
键,程序开始计时;当读者还书时,管理员输入书号并按下E
键,程序结束计时。书号为不超过1000的正整数。当管理员将0作为书号输入时,表示一天工作结束,你的程序应输出当天的读者借书次数和平均阅读时间。
注意:由于线路偶尔会有故障,可能出现不完整的纪录,即只有S
没有E
,或者只有E
没有S
的纪录,系统应能自动忽略这种无效纪录。另外,题目保证书号是书的唯一标识,同一本书在任何时间区间内只可能被一位读者借阅。
输入格式:
输入在第一行给出一个正整数N(≤10),随后给出N天的纪录。每天的纪录由若干次借阅操作组成,每次操作占一行,格式为:
书号
([1, 1000]内的整数) 键值
(S
或E
) 发生时间
(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再加上分钟之差即可
题目理解:
- 连续多次借书,以最后一次借为准,连续多次还书,以第一次还为准
操作实现:
- 定义BOOK结构体,内含开始结束时的时间hour、min和当前借阅状态state,同时定义N为1010,表示最多有1000本书,多开辟的空间防止数组越界
- 定义Time函数,计算一本书有效借阅时长
- 定义n表示统计n天借阅情况,即输出n行
- 利用for循环循环n次,内定义有效借阅次数count和当天借阅总时长time
- 利用while循环实现统计当天所有借阅归还记录,当num为0时表示当天图书馆已下班,退出while循环
- 退出while循环后,需计算并输出当日有效借阅次数和平均借阅时长
小贴士:
- 为防止在读入flag时读入空格键,可以每次输入用scanf读入一整行的数据,规范化输入
- 计算平均借阅时长时,若count==0,则会出现除零异常,需使用if-else语句输出count==0时的情况
- 四舍五入算法可以先将整数除法转化为浮点数除法,将结果加上0.5,再强转为整型,从而达到四舍五入的效果
代码实现:
#include <iostream>
#include <cstdio>
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题目地址
欢迎大家探讨