记做题时犯的错
题目地址: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.
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 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会出现错误。出现错误有两个原因:
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;
}