PAT (Advanced Level) Practice 1075 PAT Judge (25分)——测试点4

记做题时犯的错
题目地址:https://pintia.cn/problem-sets/994805342720868352/problems/994805393241260032

题目描述

The ranklist of PAT is generated from the status list, which shows the scores of the submissions. This time you are supposed to generate the ranklist for PAT.

输入格式

Each input file contains one test case. For each case, the first line contains 3 positive integers, N (≤10^​4), the total number of users, K (≤5), the total number of problems, and M (≤10^5), the total number of submissions. It is then assumed that the user id’s are 5-digit numbers from 00001 to N, and the problem id’s are from 1 to K. The next line contains K positive integers p[i] (i=1, …, K), where p[i] corresponds to the full mark of the i-th problem. Then M lines follow, each gives the information of a submission in the following format:

user_id problem_id partial_score_obtained

where partial_score_obtained is either −1 if the submission cannot even pass the compiler, or is an integer in the range [0, p[problem_id]]. All the numbers in a line are separated by a space.
​​ .

输出格式

For each test case, you are supposed to output the ranklist in the following format:

rank user_id total_score s[1] ... s[K]

where rank is calculated according to the total_score, and all the users with the same total_score obtain the same rank; and s[i] is the partial score obtained for the i-th problem. If a user has never submitted a solution for a problem, then “-” must be printed at the corresponding position. If a user has submitted several solutions to solve one problem, then the highest score will be counted.

The ranklist must be printed in non-decreasing order of the ranks. For those who have the same rank, users must be sorted in nonincreasing order according to the number of perfectly solved problems. And if there is still a tie, then they must be printed in increasing order of their id’s. For those who has never submitted any solution that can pass the compiler, or has never submitted any solution, they must NOT be shown on the ranklist. It is guaranteed that at least one user can be shown on the ranklist.

输入样例1

7 4 20
20 25 25 30
00002 2 12
00007 4 17
00005 1 19
00007 2 25
00005 1 20
00002 2 2
00005 1 15
00001 1 18
00004 3 25
00002 2 25
00005 3 22
00006 4 -1
00001 2 18
00002 1 20
00004 1 15
00002 4 18
00001 3 4
00001 4 2
00005 2 -1
00004 2 0

输出样例1

1 00002 63 20 25 - 18
2 00005 42 20 0 22 -
2 00007 42 - 25 - 17
2 00001 42 18 18 4 2
5 00004 40 15 0 25 -

解题思路

题意
有N位考生,准考证号为00001~N。共K道题,编号为1-K,且每道题的分值给出,然后给出M次提交记录,每个提交记录显示了该次提交所属考试的准考证号、所交题的题号和所得分值。其中,分值为-1(未通过编译)或0到满分之间的一个整数。
要求对所有考生按如下规则排序:
(1)按总分从高到底排序
(2)总分相同则按完美解决(或该题满分)的题目数量从高到低排序
(3)完美解决的题目数量也相同则按准考证号从小到大排序

输出:
(1)输出考生的排名、准考证号、总分、各题得分,总分相同则排名相同
(2)若考生无提交记录或没有可通过编译的提交,不输出该考生信息
(3)输出各题得分时,未通过编译的将该题记为0,未提交过的输出“-”

思路:
使用结构体放置相关信息,并使用sort()函数进行排序

注:
若某考生所有能通过编译的提交都获得0分,此时考生总分为0分,这条信息不满足“全场未提交和没有能通过编译的提交”的条件,同样需要输出。

出错点

(1)在处理输入的提交信息时,若直接使用如下语句,测试点4会出现错误。出现错误有两个原因:

  1. 在重复提交完美解决的题目时,该题已经记录在完美解决题数stu[id].solve中,重复提交时,若没有做判断,则会出现重复记录的情况;
  2. 在某题已经通过编译获得分数之后,出现再次提交且没有通过编译的情况时,会覆盖原来的已通过的信息,出现错误。所以在判断是否通过编译的时候,还应判断该题以前是否有通过编译的情况。
        scanf("%d%d%d",&id,&problem,&score);
		if(score == weight[problem - 1] )
		    stu[id].solve ++;
		if(score == -1 )
		    stu[id].score[problem - 1] = 0;
		else if(score != -1 && score > stu[id].score[problem - 1]){
			stu[id].score[problem - 1] = score;
			stu[id].submit = true;

代码

#include 
#include 
#include 

using namespace std;

struct student{
	int id;             //准考证号
	int score[6];   //每道题的得分
	int total;         //总分
	int solve;       //完美解题数
	bool submit;  //是否有能通过编译的提交
}stu[10010];
//初始化
void init(int n){
	for(int i = 1;i <= n;i ++){
		stu[i].id = i;
		stu[i].solve = 0;
		stu[i].submit = false;
		stu[i].total = 0;
		for(int j = 0;j < 6;j ++)
		    stu[i].score[j] = -1; //题目得分记为-1表示该题未提交
	}
}

bool cmp(student a,student b){
	if(a.total != b.total)
	    return a.total > b.total;
	else{
		if(a.solve != b.solve)
		    return a.solve > b.solve;
		else
		    return a.id < b.id;
	}
}

int main() {
	int n,k,m;//n-总人数,k-问题数(<=5),m-提交数
	scanf("%d%d%d",&n,&k,&m);
	init(n);
	int weight[6] = {0};
	for(int i = 0;i < k;i ++)
	    scanf("%d",&weight[i]);
	int id,score,problem;
	for(int i = 0;i < m;i ++){
		scanf("%d%d%d",&id,&problem,&score);
		if(score == weight[problem - 1] && stu[id].score[problem - 1] != score)
		    stu[id].solve ++;
		if(score == -1 && stu[id].score[problem - 1] == -1)
		    stu[id].score[problem - 1] = 0;
		else if(score != -1 && score > stu[id].score[problem - 1]){
			stu[id].score[problem - 1] = score;
			stu[id].submit = true;
		}
	}
	for(int i = 1;i <= n;i ++){
		for(int j = 0;j < k;j ++)
		    if(stu[i].score[j] != -1)
		        stu[i].total += stu[i].score[j];
	}
	sort(stu + 1,stu + n + 1,cmp);
	int rank = 1;
	for(int i = 1;i <= n && stu[i].submit == true;i ++){
		if(i > 1 && stu[i].total != stu[i - 1].total)
		    rank = i;
		printf("%d %05d %d",rank,stu[i].id,stu[i].total);   
		for(int j = 0;j < k;j ++)
			if(stu[i].score[j] == -1)
			    printf(" -");
			else
			    printf(" %d",stu[i].score[j]);
		printf("\n");
	}
	return 0;
}

你可能感兴趣的:(PAT)