BUAA(2021春)机试检测异常(简)(期末考试题)——简单排序

48 篇文章 154 订阅

看前须知

要点介绍和简要声明.

题目内容

问题描述

某教学平台具有考试登录异常检测功能,检测规则如下:

  1. 考试开始后,如果同一账号在不同机器上登录,系统将报警输出异常登录信息(可能存在私自换机器的情况);
  2. 考试开始后,如果同一账号在同一机器上多次登录,属于正常情况,系统不报警。
    编写程序,读入某次考试学生的登录日志信息,对其进行异常检测,输出异常登录信息。日志信息包括登录时间(用包含6个数字的字符串表示,例如:093756,表示9点37分56秒)、机器号(用一整数表示,不超过int的表示范围)、学生学号(即学生账号,唯一标识学生身份的信息,用一整数表示,不超过int的表示范围)、学生姓名(用不含空白符的字符串表示,字符个数不超过15)。

输入形式

先从控制台输入日志信息条数(不超过200条),然后按照登录先后顺序分行输入日志信息,每条信息包括登录时间、机器号、学号和姓名,以一个空格分隔各数据。

输出形式

按照学号从小到大的顺序输出登录异常账号信息(仅包括学号和姓名),每条信息独占一行,学号和姓名以一个空格分隔。如果没有异常登录信息,则什么都不输出。

样例

21
093000 15 191028 wangdi
093000 39 192387 litong
093001 37 190877 liugang
093004 196 197583 huangqinian
093005 201 195211 liuhao
093006 377 193098 zhaogang
093007 1 190001 zhousheng
093007 12 190009 wuhong
093008 197 197583 huangqinian
093008 202 195877 lisisi
093009 309 192387 litong
093402 201 191000 tonghao
093500 196 197583 huangqinian
093507 15 191028 wangdi
093558 85 190010 wangzhuang
093600 63 195333 zhangye
094100 195 197583 huangqinian
095103 200 195211 liuhao
095509 287 190010 wangzhuang
095606 377 193098 zhaogang
095709 15 191028 wangdi
【样例输出】
190010 wangzhuang
192387 litong

195211 liuhao

197583 huangqinian

样例说明

输入了21条登录日志信息,其中有四位学生(学号分别为190010、192387、195211和197583)在多台机器上登录,属于异常登录,输出异常账号登录信息;注意:学号为191028的学生在15号机器上有多次登录,属于正常重复登录。

题解

思路详解

送分题,分模块后,没有难度。
这个题分成三个部分:

  1. 排除上机正常的情况(机器编号和学号匹配);
  2. 找到所有的异常学号;
  3. 去重后排序;

基础的分数一定要拿到。

参考代码

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<ctype.h>
#include<stdbool.h>
int i,j; 
struct node{			//存储信息的结构体 
	char time[200];		//上机时间 
	int mID;			//机器编号 
	int sID;			//学生编号 
	char name[200];		//学生姓名 
}s[20000],ss[20000];
int num=0;
int cmp(const void*p1,const void*p2)
{
	struct node *a=(struct node*)p1;
	struct node *b=(struct node*)p2;
	return a->sID-b->sID;	//根据学生编号排序 
}
int main()
{	
	int n;
	scanf("%d",&n);		//输入个数 
	for(i=0;i<n;i++)
	{
		scanf("%s %d %d %s",s[i].time,&s[i].mID,&s[i].sID,s[i].name);//录入信息 
	}
	for(i=0;i<n;i++)
	{
		for(j=i+1;j<n;j++)
		{
			if(s[i].sID==s[j].sID && s[i].mID==s[j].mID)	
			//找到在同一个机器上上机的同学,由于是正常情况,所以删去 
			{
				s[j].mID=s[j].sID=0;
				memset(s[j].name,0,sizeof(s[j].name));
				memset(s[j].time,0,sizeof(s[j].time));
			}
		}
	}
	
	for(i=0;i<n;i++)
	{
		for(j=i+1;j<n;j++)
		{
			if(s[i].sID==s[j].sID && s[i].mID!=s[j].mID)
			//找到学生编号相同,但是在多个机器上登录的一场情况 
			{
				ss[num].mID=s[i].mID;	//复制到ss里面,方面后序操作 
				ss[num].sID=s[i].sID;	
				strcpy(ss[num].name,s[i].name);
				strcpy(ss[num].time,s[i].time);
				num++;	//记录异常的数目 
			}
		}
	}
	for(i=0;i<num;i++)
	{
		for(j=i+1;j<num;j++)
		{
			if(strcmp(ss[i].name,ss[j].name)==0)	//去重 
			{
				ss[j].sID=-1;
			}
		}
	}
	qsort(ss,num,sizeof(struct node),cmp);//根据学号排序 
	for(i=0;i<num;i++)
	{
		if(ss[i].sID>0)		//输出非重复的学号和姓名 
			printf("%d %s\n",ss[i].sID,ss[i].name);
	}
	
	return 0;
}

补充测试的数据

其实吧,通过样例其实要考虑的情况就基本全了

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值