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.
Input Specification:
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:
属于排序
的一种题型,但是处理数据要求很高,部分分容易,全部分需要做出很多思考,加深对题目的理解
我遇到的一个最麻烦的就是:
特别要注意的是,id的初始值问题。一开始没留心这个问题,一个测试用例过不去,纠结了好久。
id的初始值为0,意味着,它会被排在所有总分为0的学生前面!因此,id需要初始化为最大值。这样初始化之后就会被排在最后了,到时候flag=0 break即可
这个摘自其他博客,感觉说的有点道理,但是一般可以不必初始化这个值,我们有一个flag可以用来搞定这种情况,flag
为0一律continue
(不要使用break)记得更新rank要在continue之前,确保后续那些WA了好几发还是零的同学可以上榜,而且排名正确
#include <bits/stdc++.h>
using namespace std;
struct stu
{
int num;
int ti[6];
int perfect;//记录AC的个数
int total;//记录总分
int flag;//判断是否可以输出
stu(){
for(int i=0;i<=5;i++){
ti[i]=-2;//初始化为-2方便判断输出
}
}
}s[100010];//开的大一点也问题不大
int cmp(stu a,stu b){//自定义结构体三级比较
if(a.total!=b.total){//大-----------------小 降序
return a.total>b.total;
}
else if(a.perfect!=b.perfect){
return a.perfect>b.perfect;
}
else{
return a.num<b.num;
}
}
int main(){
int N,K,M;
cin>>N>>K>>M;
int p[K+1];
for(int i=1;i<=K;i++){
cin>>p[i];
}
for(int i=1;i<=M;i++){
int a,pid,score;
cin>>a;
s[a].num=a;
cin>>pid>>score;
if(score!=-1){
s[a].flag=1;
}
s[a].ti[pid]=max(s[a].ti[pid],score);//保留最大值
}
for(int i=1;i<=N;i++){//统一整理O(N)不用担心超时
for(int j=1;j<=K;j++){
if(s[i].ti[j]>=0){//大于等于0的才计算
s[i].total+=s[i].ti[j];
}
if(s[i].ti[j]==p[j]){
s[i].perfect++;
}
}
}
sort(s+1,s+N+1,cmp);
int rank=0;
int grade=-1;
for(int i=1;i<=N;i++){//可以学习一下rank的计算过程
if(s[i].total!=grade){
grade=s[i].total;
rank=i;
}
if(s[i].flag==0) continue;
printf("%d %05d %d",rank,s[i].num,s[i].total);
for(int j=1;j<=K;j++){
if(s[i].ti[j]>=0){
printf(" %d",s[i].ti[j]);
}
else if(s[i].ti[j]==-1){
printf(" 0");
}
else{
printf(" -");
}
}
printf("\n");
}
return 0;
}