BUAA数据结构2023级期末考试第一题

【问题描述】

某学校要求学生每天课后锻炼一小时以上,每个锻炼地点都有打卡记录。请根据输入的运动打卡记录,统计并输出每位学生的锻炼时长和打卡次数。

【输入形式】

先输入打卡记录数(不超过1000),然后按照时间序分行输入每位学生的打卡记录,每行的信息格式如下:

<学号> <开始时间> <结束时间>

<学号>:以字母B(表示本科生)、M(表示硕士研究生)和D(表示博士研究生)开头,其它六位均为数字的符号串,如B230011、M236123、D220456。

<开始时间>和<结束时间>:HH MM SS。分别表示时、分、秒,采用24小时制,时间不存在跨天的情况,时、分和秒间以一个空格分隔。

上述信息间以一个空格分隔。

【输出形式】

按学号(本科、硕研、博研先后序)分类输出每位学生的锻炼时长及打卡次数,同一学生分类中按锻炼时长由小到大输出(同一学生分类中不存在锻炼时长相同的学生),输出的每行学生信息格式如下:

<学号> <时长> <打卡次数>

<时长>:如1.11(单位为小时,小数点后保留二位)

上述信息间以一个空格分隔。

【样例输入】

28

B230330 06 00 08 07 02 56

B230326 06 00 10 06 31 09

M220160 06 30 02 07 02 56

B230312 06 50 03 07 12 56

D230126 07 00 02 07 25 01

M220126 07 00 03 07 30 08

B230101 09 30 00 10 31 05

B230330 10 00 07 11 00 10

B230326 10 00 10 11 30 00

M220126 14 05 06 15 06 25


B230330 15 00 07 16 00 10

B230326 15 00 10 16 00 15

D220028 16 00 05 18 30 09

M230507 16 30 06 17 38 56

D210037 17 00 00 17 47 39

D220012 17 00 01 17 47 40

D230126 17 03 56 18 15 55

B230108 17 59 58 19 02 10


B230312 18 00 00 19 02 07

B230101 18 00 01 19 02 06

B230102 18 00 02 19 02 08

D210037 18 02 00 18 40 22

D220012 18 02 05 18 35 56

M230507 19 00 35 20 30 23

B230326 20 00 10 21 33 01

M220126 20 05 03 22 04 01

M220156 20 05 06 22 04 05

M220160 20 05 08 22 04 03

【样例输出】

B230102 1.03 1

B230108 1.04 1

B230312 1.42 2

B230101 2.05 2

B230330 3.05 3

B230326 4.56 4

M220156 1.98 1

M220160 2.53 2

M230507 2.64 2

M220126 3.51 3

D220012 1.36 2

D210037 1.43 2

D230126 1.62 2

D220028 2.50 1

【样例说明】

输入了28个打卡记录,其中学号为B230101的学生打卡了2次,两次运动分别耗时3665秒、3725秒,共7390秒,约为2.05小时;其它学生类似。

【评分标准】

该题要求对学生打卡运动时长和打卡次数进行统计,并分类排序。仅对学生运动时长进行排序也可得一定分数。提交程序名为time.c。

【思路】
1.根据题意开一个结构体数组存储相关数据
2.存储【学号】【时间】【次数】信息,同时通过遍历1.中提到的数组数据填入时间与次数信息,需要考虑的是输出数据精度,我们选择将始末时间先转化为s相减后再转化为小时来保证数据准确
3.使用qsort依据时间来排序时要注意修改cmp函数(因为时间是一个浮点数,而cmp返回值是int)
4.至于本硕博的排序可以多建几个结构体数组分别储存学号、时间、次数等,再分别输出即可
 

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX 1024

typedef struct s1{
	char id[10];
	double bh;
	double bm;
	double bs;
	double fh;
	double fm;
	double fs;
	double cnt;
	double time;
}s1;

s1 ex[MAX];


typedef struct s2{
	char id[10];
	double time;
	int cnt;
}s2;

s2 b[MAX],m[MAX],d[MAX];

int cmp(const void*a,const void*b)
{
	double x=((struct s2*)a)->time;
	double y=((struct s2*)b)->time;
	if(x>y) return 1;
	else if(x==y) return 0;
	else if(x<y) return -1;
}

int main()
{
	int n;
	scanf("%d",&n);
	for(int i=0;i<n;i++)
	{
		scanf("%s %lf %lf %lf %lf %lf %lf",ex[i].id,&ex[i].bh,&ex[i].bm,&ex[i].bs,&ex[i].fh,&ex[i].fm,&ex[i].fs);
		ex[i].cnt++;
	}
	
	for(int i=0;i<n;i++)
	{
		ex[i].time=(ex[i].fh*3600+ex[i].fm*60+ex[i].fs-ex[i].bh*3600-ex[i].bm*60-ex[i].bs)/3600;
	}//处理时间 
	for(int i=0;i<n;i++)
	{
		for(int j=i+1;j<n;j++)
		{
			if(strcmp(ex[i].id,ex[j].id)==0&&ex[j].cnt!=-1)
			{
				ex[i].cnt+=ex[j].cnt;
				ex[i].time+=ex[j].time;
				ex[j].cnt=-1;
			}
		}
	}
	
	int count=0;
	for(int i=0;i<n;i++)
	{
		if(ex[i].id[0]=='B'&&ex[i].cnt!=-1)
		{
			strcpy(b[count].id,ex[i].id);
			b[count].cnt=ex[i].cnt;
			b[count++].time=ex[i].time;
		}
	}
	
	qsort(b,count,sizeof(struct s2),cmp);
	for(int i=0;i<count;i++)
	{
		printf("%s %.2lf %d\n",b[i].id,b[i].time,b[i].cnt);
	}
	
	count=0;
	for(int i=0;i<n;i++)
		{
			if(ex[i].id[0]=='M'&&ex[i].cnt!=-1)
			{
				strcpy(m[count].id,ex[i].id);
				m[count].cnt=ex[i].cnt;
				m[count++].time=ex[i].time;
			}
		}
		qsort(m,count,sizeof(struct s2),cmp);
		for(int i=0;i<count;i++)
		{
			printf("%s %.2lf %d\n",m[i].id,m[i].time,m[i].cnt);
		}
	count=0;
		for(int i=0;i<n;i++)
			{
				if(ex[i].id[0]=='D'&&ex[i].cnt!=-1)
				{
					strcpy(d[count].id,ex[i].id);
					d[count].cnt=ex[i].cnt;
					d[count++].time=ex[i].time;
				}
			}
			
			qsort(d,count,sizeof(struct s2),cmp);
			for(int i=0;i<count;i++)
			{
				printf("%s %.2lf %d\n",d[i].id,d[i].time,d[i].cnt);
			}
	
	return 0;
}


 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值