PAT-1012 The Best Rank (25)

题目大意:各考生的 C 程序设计、数学、英语成绩已知,并可以算出平均分(计算总分即可),各门课和总成绩共 4 项成绩单独排名,询问各学生在这 4 项排名中的最高名次和对应科目输出;如果最高排名有多个,则输出按照 总分 > C程序设计 > 数学 > 英语 的优先级至多选取一门课输出。

解题思路:本题就是暴力模拟,采用结构体存储信息。用 map 记住名字对应的输入顺序号,避免之后的查找;然后就是 4 个排序,计算各门课的排行,用相应的记号来记录(注意排名的处理,比如并列第一有两个,那么分第二高的就是第三名......);还原结构体,进行询问。PS:代码不优美,勿喷~~

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

#include <iostream>        
#include <algorithm>        
#include <set>        
#include <map>        
#include <vector>        
#include <stack>        
#include <queue>        
#include <cmath>     
#include <cstring>       
using namespace std; 

typedef struct stuInfo{
	char name[15];
	int a,c,m,e,id;
	int rankA,rankC,rankM,rankE;
}stuInfo;

stuInfo stu[10005],stuCopy[10005];

map<string,int> nameToNum;//记住 id 对应 name,避免顺序查找 

bool cmp1(stuInfo x1,stuInfo x2)
{
	if(x1.a > x2.a)
		return true;
	return false;
}

bool cmp2(stuInfo x1,stuInfo x2)
{
	if(x1.c > x2.c)
		return true;
	return false;
}

bool cmp3(stuInfo x1,stuInfo x2)
{
	if(x1.m > x2.m)
		return true;
	return false;
}

bool cmp4(stuInfo x1,stuInfo x2)
{
	if(x1.e > x2.e)
		return true;
	return false;
}

int main(int argc, char** argv) {
	int n,m;
	cin >> n >> m;
	for(int i=0;i<n;++i)
	{
		scanf("%s %d %d %d",&stu[i].name,&stu[i].c,&stu[i].m,&stu[i].e);
		stu[i].a = (stu[i].c+stu[i].m+stu[i].e);
		stu[i].id = i;
		nameToNum[stu[i].name] = i; 
	}
	//Average 
	sort(stu,stu+n,cmp1);
	stu[0].rankA = 1;
	for(int i=1;i<n;++i)
	{
		if(stu[i].a != stu[i-1].a)
		{
			stu[i].rankA = i+1;
		}
		else
		{
			stu[i].rankA = stu[i-1].rankA;
		}
	}
	
	// C Programming  
	sort(stu,stu+n,cmp2);
	stu[0].rankC = 1;
	for(int i=1;i<n;++i)
	{
		if(stu[i].c != stu[i-1].c)
		{
			stu[i].rankC = i+1;
		}
		else
		{
			stu[i].rankC = stu[i-1].rankC;
		}
	}
	
	//Mathematics
	sort(stu,stu+n,cmp3);
	stu[0].rankM = 1;
	for(int i=1;i<n;++i)
	{
		if(stu[i].m != stu[i-1].m)
		{
			stu[i].rankM = i+1;
		}
		else
		{
			stu[i].rankM = stu[i-1].rankM;
		}
	}
	
	//English
	sort(stu,stu+n,cmp4);
	stu[0].rankE = 1;
	for(int i=1;i<n;++i)
	{
		if(stu[i].e != stu[i-1].e)
		{
			stu[i].rankE = i+1;
		}
		else
		{
			stu[i].rankE = stu[i-1].rankE;
		}
	}
	
	
	//还原 
	for(int i=0;i<n;++i)
	{
		stuCopy[stu[i].id] = stu[i];
	}
	
	for(int i=0;i<m;++i)
	{
		char a[15];
		cin >> a;
		if(nameToNum.count(a) == 0)
		{
			cout << "N/A" << endl;
			continue;
		}
		int pos = nameToNum[a];
		int rA,rC,rM,rE;
		rA = stuCopy[pos].rankA;
		rC = stuCopy[pos].rankC;
		rM = stuCopy[pos].rankM;
		rE = stuCopy[pos].rankE;
		int Min = min(min(rA,rC),min(rM,rE));
		cout << Min;
		if(Min == rA)
			cout << " A" << endl;
		else if(Min == rC)
			cout << " C" << endl;
		else if(Min == rM)
			cout << " M" << endl;
		else if(Min == rE)
			cout << " E" << endl;
	}
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值