福大OJ 多关键字排序和排名

本博客介绍了一个OJ系统中学生解题情况的统计与排序算法,通过计算解题数目、提交次数和正确比例,实现了对学生完成情况的多关键字排序,详细解释了排序逻辑和并列规则。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

多关键字排序和排名

Description

下面是某一届学生在OJ系统某一时刻的完成情况统计(学生总数不超过170人):

学号 姓名 解题数目 提交次数

222200221 高艳红 77 124

222200116 吴志赟 80 90

222200240 高一鑫 80 173

222200111 唐焕翔 81 157

学号用字符串存放(长度为9),姓名最多5个汉字,0<=解题数目、提交次数<100000。

现要求编程完成下述功能:

(1)读入学生总数和这些学生的学号、姓名、解题数目、提交次数信息(假定数据都满足前面的规定);

(2)为每个学生自动计算其"正确比例"(保留2位小数,第3位小数四舍五入);

(3)先按"解题数目",再按"正确比例"从高到低排序,如果它们都相同,就按"学号"从小到大排序;

(4)输出上述完整的OJ系统完成情况统计表。

如果"解题数目"和"正确比例"都相同,则名次并列。并列规则:有2个第1名,则第3个人的名次为第3名。

输出格式规定:名次4位左对齐,学号9+3位左对齐,姓名10+1位左对齐,解题数目和提交次数6位右对齐,正确比例8位2位小数右对齐。

Input

第1行为学生总数 第2行开始,每行为1个学生的学号、姓名、解题数目、提交次数(均用空格分开)

Output

已经按题目要求排序后的OJ系统完成情况统计表。 每行为1个学生的排名、学号、姓名、解题数目、提交次数、正确比例

Sample Input 1

13
222200221 高艳红 77 124
222200116 吴志赟 80 90
222200201 翁诗宁 80 147
222200127 王建洲 80 128
222200128 曾荣流 80 332
222200125 张明星 80 128
222200203 李长泉 80 110
222200212 胡武扬 80 154
222200219 张华荣 80 198
222200227 刘成斌 80 117
222200240 高一鑫 80 173
222200101 流叶笛 81 150
222200111 唐焕翔 81 157

Sample Output 1

1 222200101 流叶笛 81 150 54.00%
2 222200111 唐焕翔 81 157 51.59%
3 222200116 吴志赟 80 90 88.89%
4 222200203 李长泉 80 110 72.73%
5 222200227 刘成斌 80 117 68.38%
6 222200125 张明星 80 128 62.50%
6 222200127 王建洲 80 128 62.50%
8 222200201 翁诗宁 80 147 54.42%
9 222200212 胡武扬 80 154 51.95%
10 222200240 高一鑫 80 173 46.24%
11 222200219 张华荣 80 198 40.40%
12 222200128 曾荣流 80 332 24.10%
13 222200221 高艳红 77 124 62.10%

Hint

严格按要求的格式输出。

源码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct Student{
	char stuNum[10];   //学生学号 
	char stuName[11];  //学生姓名,汉字一个2字节 
	int solveNum;   //解题数 
	int submitNum;  //提交次数 
	float acceptRate;  //正确比例 
};

int cmp(const void* a,const void* b)  //结构体排序函数,小于0则说明第一个减数小 
{
	struct Student* c1=(struct Student*)a;
	struct Student* c2=(struct Student*)b;
	if(c1->solveNum==c2->solveNum)
	{
		if(c1->submitNum==c2->submitNum)
		{
			return strcmp(c1->stuNum,c2->stuNum);
		}
		else return c1->submitNum-c2->submitNum;
	} 
	else return c2->solveNum-c1->solveNum;
}

struct Student SE[175];  //软件工程系学生总人数 

int main(void)
{
//	freopen("input/multiplysort.txt","r",stdin);
	int n,ranking=1,pastSolveNum=0,pastSubmitNum=0;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%s%s%d%d",SE[i].stuNum,SE[i].stuName,&SE[i].solveNum,&SE[i].submitNum);
		SE[i].acceptRate=(float)SE[i].solveNum/SE[i].submitNum*100.0;
	}
	qsort(SE+1,n,sizeof(SE[0]),cmp);
	for(int i=1;i<=n;i++)
	{
		if(SE[i].solveNum!=pastSolveNum||SE[i].submitNum!=pastSubmitNum)
		{
			ranking=i;
		}
		pastSolveNum=SE[i].solveNum;
		pastSubmitNum=SE[i].submitNum;
		printf("%-4d%-12s%-11s%6d%6d%8.2f%%",ranking,SE[i].stuNum,SE[i].stuName,SE[i].solveNum,SE[i].submitNum,SE[i].acceptRate);
		if(i!=n) printf("\n");
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值