PAT A1075 PAT Judge

题目描述

分析:排序;排序的顺序是总分大>满分通过的数目多>学生id小。这道题模仿PAT的得分情况对其排序进行输出。

知识点

排序题

实现

码前思考

  1. 就是多重条件排序
  2. 我测试点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;
} 

码后反思

  1. 后面再回来做,今天有点烦躁了。。。

~~测试点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-1pre不匹配~~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值