题意:
根据PAT提交记录进行排名,先按总分最高排名,相同再按满分的题数从大到小排名,最后按id从小到大排名。-1表示没有通过编译器,要排除没有通过编译器的用户和没有提交记录的用户。
解法:
用id当下标,建立二维数组记录每个问题的分数,用-2初始化所有的分数,-1代表没有通过,保存每一个用户的每个问题的最高分,然后统计总分,然后判断是否有通过编译的,有则将id加入到vector中,然后通过id获取相应的值进行排序输出,通过判断和前一个的总分是否相等,确定排名。
总结:
这一题一开始要想好如何存储数据,不难偏繁琐。通过编译但是分数为0分的也算在里面,这一点要注意。
(用时:56:01.39)
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<vector>
#include<set>
#include<map>
#include<stack>
#include<cstring>
#include<cmath>
//#include<bits/stdc++.h>
using namespace std;
const int INF = 10005;
int allScore[INF]= {0};
int perfectSolved[INF]= {0};
int getScore[INF][5];
int cmp(int a,int b)
{
if(allScore[a] >allScore[b] ) {
return 1;
} else if(allScore[a]==allScore[b]) {
if(perfectSolved[a] > perfectSolved[b]) {
return 1;
} else if(perfectSolved[a] == perfectSolved[b]) {
return a<b;
}
}
return 0;
}
int main()
{
int n,k,m;
scanf("%d%d%d",&n,&k,&m);
for(int i=1; i<n+1; i++) {
for(int j=0; j<k; j++) {
getScore[i][j]=-2;
}
}
int p[k];
for(int i=0; i<k; i++) {
scanf("%d",&p[i]);
}
int userID,pID,score;
for(int i=0; i<m; i++) {
scanf("%d%d%d",&userID,&pID,&score);
if(score > getScore[userID][pID-1]) {
getScore[userID][pID-1] = score;
}
}
vector<int> validUser;
for(int i=1; i<n+1; i++) {
int first = 1;
for(int j=0; j<k; j++) {
if(getScore[i][j]>-1) {
allScore[i] += getScore[i][j];
if(getScore[i][j]==p[j]) {
perfectSolved[i]++;
}
if(first==1 &&getScore[i][j]>-1 ) {
validUser.push_back(i);
first = 0;
}
}
}
}
sort(validUser.begin(),validUser.end(),cmp);
int rankNum=1;
for(int i=0; i<validUser.size(); i++) {
userID = validUser[i];
if(i==0||allScore[userID]!=allScore[validUser[i-1]]) {
rankNum = i+1;
}
printf("%d %05d %d",rankNum,userID,allScore[userID]);
for(int j=0; j<k; j++) {
if(getScore[userID][j]==-2) {
printf(" -");
} else if(getScore[userID][j]==-1) {
printf(" 0");
} else {
printf(" %d",getScore[userID][j]);
}
}
printf("\n");
}
return 0;
}