1012. The Best Rank (25)

题目链接:https://www.patest.cn/contests/pat-a-practise/1012

解题思路:按照平均成绩,C语言成绩,数学成绩,外语成绩依次排序,然后记录排名最好的成绩,利用一个map查询当前这个人是否在输入的数据中。很繁琐,我恨透了这样的题,但是请把它做出来了再骂!
女子为好,先骂为敬。我透!

#include <cstdio>
#include <cstring>
#include <map>
#include <cmath>
#include <algorithm>
using namespace std;
const int maxn = 1000005;
const int maxx = 2018;

struct E{
	int name;
	int a,c,m,e,best;
	int grade[4]; //0-3来记录每一科的排名 
	char item;
	E(){  //构造函数用来初始化的 
		best = maxx;
		item = 'G';
	}
}s[maxx]; 

bool cmp0(E a,E b){
	if(a.a != b.a) return a.a >b.a;
}
bool cmp1(E a,E b){
	if(a.c != b.c) return a.c >b.c;
}
bool cmp2(E a,E b){
	if(a.m != b.m) return a.m >b.m;
}
bool cmp3(E a,E b){
	if(a.e != b.e) return a.e >b.e;
}

int main(){
	int n,m;
	map<int,int> mp; 
	scanf("%d%d",&n,&m);
	for(int i=0;i<n;i++){
		scanf("%d%d%d%d",&s[i].name,&s[i].c,&s[i].m,&s[i].e);
		s[i].a=int((s[i].c+s[i].m+s[i].e)/3.0+0.5); //四舍五入 
		mp[s[i].name] = i;
	}
	sort(s,s+n,cmp0); //先排平均成绩 
	s[0].grade[0] = 1;
	s[0].best = 1;
	s[0].item = 'A';
	for(int i=1;i<n;i++){
		if(s[i-1].a == s[i].a){
			s[i].grade[0]=s[i-1].grade[0];
		}else{
			s[i].grade[0]=i+1;
		}
		if(s[i].grade[0]<s[i].best){
			s[i].best = s[i].grade[0];
			s[i].item = 'A';
		}
	}
	
	sort(s,s+n,cmp1); //再排C语言的成绩 
	s[0].grade[1] = 1;
	if(s[0].item != 'A') s[0].item = 'C';//根据本次排名,如果c语言的第一名,在A平均成绩中没有取得第一名,则赋值给C语言科目 
	if(s[0].best>1) {  //如果第一名在A平均成绩中的排名不及这次,则更新最好排名,并附上科目 
		s[0].best =1;
		s[0].item ='C';
	}
	for(int i=1;i<n;i++){ //对除了第一名的人遍历 
		if(s[i-1].c==s[i].c){  //如果两者成绩相同,则取得相同排名 
			s[i].grade[1]=s[i-1].grade[1];
		}else{
			s[i].grade[1]=i+1; //如果两者成绩不同,则取得前面人数总和的下一个名次。 
		}
		
		if(s[i].grade[1] < s[i].best){ //如果当前排名比最佳排名更好一些,则更新 
			s[i].best = s[i].grade[1];
			s[i].item = 'C';
		}
	}

	sort(s,s+n,cmp2); //再排数学的成绩 
	s[0].grade[2] = 1;
	if(s[0].item != 'A'&&s[0].item!='C') s[0].item = 'M';
	if(s[0].best>1) {
		s[0].best =1;
		s[0].item ='M';
	}
	for(int i=1;i<n;i++){
		if(s[i-1].m==s[i].m){
			s[i].grade[2]=s[i-1].grade[2];
		}else{
			s[i].grade[2]=i+1;
		}
		if(s[i].grade[2]<s[i].best){
			s[i].best = s[i].grade[2];
			s[i].item = 'M';
		}
	}
	
	sort(s,s+n,cmp3); //最后排英语的成绩 
	s[0].grade[3] = 1;
	if(s[0].item != 'A'&&s[0].item!='C'&&s[0].item !='M') s[0].item = 'E';
	if(s[0].best>1) {
		s[0].best =1;
		s[0].item = 'E';
	}
	for(int i=1;i<n;i++){
		if(s[i-1].e==s[i].e){
			s[i].grade[3]=s[i-1].grade[3];
		}else{
			s[i].grade[3]=i+1;
		}
		if(s[i].grade[3]<s[i].best){
			s[i].best = s[i].grade[3];
			s[i].item = 'E';
		}
	}


	int query;
	for(int i=0;i<m;i++){
		scanf("%d",&query);
        if(mp.find(query)==mp.end()){ //用了一下map方便查询,其实也可以用哈希 
        	printf("N/A\n");
        	continue;
		}
		for(int i=0;i<n;i++){ //这里又遍历了一遍感觉时间复杂度有点大了 但是还是过了 题目的限制很宽松 
			if(s[i].name == query){
				printf("%d %c\n",s[i].best,s[i].item);
				break;
			}
				
		}	
    }
	return 0;
}

版本2

牛客网测试点
1.ID必须是字符串类型,不能用整数存。
2.求平均分时直接向下取整,而不是四舍五入。

#include<iostream>
#include<cstdio>
#include<string>
#include<vector>
#include<algorithm>
#include<unordered_map>
using namespace std;
int w = 0; 
struct stu{
	int id, c, m, e, a;
	int cc, mm, ee, aa; //排名 
}E[2005];

bool cmp(stu a, stu b){
	if (w == 0) return a.a > b.a;  
	else if(w == 1) return a.c > b.c;
	else if(w == 2) return a.m > b.m;
	else return a.e > b.e;
}
void print(int x){
	char ch = 'A';
	int d = E[x].aa;
	if(d > E[x].cc) d = E[x].cc, ch = 'C'; 
	if(d > E[x].mm) d = E[x].mm, ch = 'M';
	if(d > E[x].ee) d = E[x].ee, ch = 'E';
	cout<<d<<" "<<ch<<endl;
}
int main(){
	int n, m, x, score;
	unordered_map<int, int> mp;
	cin >> n >> m;
	for(int i = 0; i < n; i++){
		cin>>E[i].id >>E[i].c >> E[i].m>>E[i].e;
		E[i].a = (E[i].c + E[i].m + E[i].e)/3.0 + 0.5 ;
	}
	sort(E, E + n, cmp);
	for(int i = 0 ; i < n; i++){ //相同成绩相同排名 
		if(i > 0 && E[i-1].a == E[i].a) E[i].aa = E[i-1].aa;
		else E[i].aa = i + 1;
	} 
	w=1;
	sort(E, E + n, cmp);
	for(int i = 0 ; i < n; i++){
		if(i > 0 && E[i-1].c == E[i].c) E[i].cc = E[i-1].cc;
		else E[i].cc = i + 1;
	} 
	w=2;
	sort(E, E + n, cmp);
	for(int i = 0 ; i < n; i++){
		if(i > 0 && E[i-1].m == E[i].m) E[i].mm = E[i-1].mm;
		else E[i].mm = i + 1;
	} 
	w=3;
	sort(E, E + n, cmp);
	for(int i = 0 ; i < n; i++){
		if(i > 0 && E[i-1].e == E[i].e) E[i].ee = E[i-1].ee;
		else E[i].ee = i + 1;
		mp[E[i].id] = i + 1; 
	} 
	while(m--){
		cin >> x;
		if(!mp[x]) cout<<"N/A"<<endl;
		else{
			print(mp[x] - 1);
		} 
	}
	return 0;
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值