【1075】PAT Judge (25 分)

程序竞赛评分系统解析
本文深入探讨了一种程序竞赛的评分系统实现,包括初始化学生信息、处理提交记录、计算总分和进行排序的过程。系统考虑了多种情况,如编译错误、得分更新和完美解题等,确保了评分的公平性和准确性。
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
#include<algorithm>  
#include<map>
#include<vector>
#include<queue> 
using namespace std;  
//key:很多陷阱,注意同一题如果后面提交分数比前面低分,不会覆盖
//没有提交或没有能通过编译的提交的童鞋不需要输出(flag判断)
//所有能通过编译的提交都获得了0分仍然要输出

const int maxn=10010;
struct Student{
	int id;   //准考证号
	int score[6];  //每道题的得分
	bool flag; //是否有能够通过编译的提交
	int score_all;  //总分
	int solve;  //完美解题数
}stu[maxn];
int n,k,m;
int full[6]; //每道题的满分
bool cmp(Student a,Student b){ //排序函数
	if(a.flag != b.flag)  return a.flag>b.flag; //需要输出的考生排在前面
	else if(a.score_all != b.score_all)  return a.score_all>b.score_all;
	else if(a.solve != b.solve)  return a.solve>b.solve;
	else return a.id< b.id;
}
void init(){ //初始化
	for(int i=1;i<=n;i++){ 
		stu[i].id = i;  //准考证号记为i
		stu[i].score_all=0;  //总分初始化为0
		stu[i].solve=0;  //完美解题数初始化为0
		stu[i].flag=false;  //初始化为没有能通过编译的提交
		memset(stu[i].score , -1 , sizeof(stu[i].score)); //题目得分记为-1(6道题)
	}
}
  
int main(){   
	scanf("%d%d%d",&n,&k,&m);
	init();
	for(int i=1;i<=k;i++){ 
		scanf("%d",&full[i]); //每道题目的满分数
	}
	int u_id,p_id,score_obtained; //考生ID 题目ID及所获分值
	for(int i=0;i<m;i++){ 
		scanf("%d%d%d",&u_id,&p_id, &score_obtained);
		if(score_obtained !=-1){ //若不是编译错误,则该考生有能够通过编译的提交
			stu[u_id].flag=true;
		}
		if(score_obtained == -1 && stu[u_id].score[p_id] == -1){ 
			//某题第一次编译错误,分值记为0分,便于输出
			stu[u_id].score[p_id]=0;
		}
		if(score_obtained==full[p_id] && stu[u_id].score[p_id]<full[p_id]){
			stu[u_id].solve++; //某题第一次获得满分,则完美解题数加1
		}
		if(score_obtained>stu[u_id].score[p_id]){ 
			stu[u_id].score[p_id]=score_obtained; //某题获得更高分值,则覆盖
		}
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=k;j++){
			if(stu[i].score[j] != -1){  //计算总分
				stu[i].score_all += stu[i].score[j];
			}
		}
	}
	sort(stu+1,stu+n+1,cmp); //按要求排序,注意n+1
	int r=1;  //当前排名
	for(int i=1;i<=n && stu[i].flag == true;i++){ 
		if(i>1 && stu[i].score_all !=stu[i-1].score_all){
			//当前考生分数低于前一位考生分数,则排名为在该考生之前的总考生数
			//注意在此之前已经是"排序"了
			r=i;
		}
		printf("%d %05d %d",r, stu[i].id, stu[i].score_all);
		for(int j=1;j<=k;j++){
			if(stu[i].score[j] == -1){ 
				printf(" -"); //没有过提交
			}else{
				printf(" %d",stu[i].score[j]); //注意此处第一个分数前也是有空格的
			}
		}
		printf("\n");
	}
	system("pause"); 
    return 0;   
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

山顶夕景

小哥哥给我买个零食可好

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值