题目描述
分析:排序;排序的顺序是总分大>满分通过的数目多>学生id小。这道题模仿PAT的得分情况对其排序进行输出。
知识点
排序题
实现
码前思考
- 就是多重条件排序
- 我测试点4没有过,不知道是为什么。。。
代码实现
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct node{
int rank,id,total = 0;
vector<int> score;
int passnum = 0;
bool isshown =false;
};
bool cmp1(node a,node b){
//注意是不等号
if(a.total != b.total)
return a.total > b.total;
else if(a.passnum != b.passnum)
return a.passnum > b.passnum;
else
return a.id<b.id;
}
int main(){
int n,k,m,id,num,score;
scanf("%d %d %d",&n,&k,&m);
vector<node> v(n+1);
for(int i=1;i<=n;i++){
v[i].score.resize(k+1,-1);
}
vector<int> full(k+1);
for(int i=1;i<=k;i++){
scanf("%d",&full[i]);
}
for(int i=0;i<m;i++){
scanf("%d %d %d",&id,&num,&score);
v[id].id = id;
//避免覆盖,选择最大值
v[id].score[num] = max(v[id].score[num],score);
if(score != -1){
v[id].isshown = true;
}else if(v[id].score[num] == -1){
//代表编译不通过
v[id].score[num] = -2;
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=k;j++){
if(v[i].score[j] != -1 && v[i].score[j] != -2){
v[i].total += v[i].score[j];
}
if(v[i].score[j] == full[j]){
v[i].passnum++;
}
}
}
sort(v.begin()+1,v.end(),cmp1);
for(int i=1;i<=n;i++){
v[i].rank = i;
if(i != 1 && v[i].total == v[i-1].total){
v[i].rank = v[i-1].rank;
}
}
for(int i=1;i<=n;i++){
if(v[i].isshown == true){
printf("%d %05d %d",v[i].rank,v[i].id,v[i].total);
for(int j=1;j<=k;j++){
if(v[i].score[j] != -1 && v[i].score[j] != -2){
printf(" %d",v[i].score[j]);
}else if(v[i].score[j] == -1){
printf(" -");
}else{
printf(" 0");
}
}
printf("\n");
}
}
return 0;
}
码后反思
- 后面再回来做,今天有点烦躁了。。。
~~测试点2:
之前的代码中,在考虑测试提交通过实得0分和提交编译不通过定义为0分的区分时,没有考虑两者的排序关系,导致,最后出现错误!出错代码如下:
bool cmp(node a,node b){
if(a.tot > b.tot){
return true;
}else if(a.tot == b.tot){
//相等比较ac数
if(a.acCnt> b.acCnt){
return true;
}else if(a.acCnt == b.acCnt){
//比较id大小
return a.uid < b.uid;
}else{
return false;
}
}else{
return false;
}
}
...
...
...
for(int i=1;i<n+1;i++){
//对于分数为0,而且没用通过编译的人直接中断
//没有提交过也是没有编译过
if(nodes[i].passCmp == false){
continue;
}else{
//如果与前面的分数相同
if(nodes[i].tot == nodes[i-1].tot){
printf("%d %05d %d",pre,nodes[i].uid,nodes[i].tot);
}else{
printf("%d %05d %d",rank,nodes[i].uid,nodes[i].tot);
pre = rank;
}
//从1开始
for(int j=1;j<=k;j++){
if(nodes[i].scores[j]!=-1){
printf(" %d",nodes[i].scores[j]);
}else{
printf(" -");
}
}
printf("\n");
rank++;
}
}
没有考虑到如果编译不成功的在实际得0分之前的话,虽然能够跳过编译不成功的,但是在计算rank的时候会有问题,因为你比较的i-1
与pre
不匹配~~