题目
解题思路
这个题要AC其实不容易,思路不太好理清,又是横向排序,又是纵向排序,我最开始做这个题有点凌乱,所以来整理一下思路:
- 首先一个结构体存储学生信息是少不了的,那这个结构体包含什么呢?id肯定是少不了的,这里要考虑用string还是int,如果用int,那么意味着你要开辟一个比较大的数组。用string的好处在于可以有很多成员函数使用,这里我用的是int。
- 成绩也是少不了的,那么我们用grade数组来存取ACME,一定是这个顺序,因为题目有一个权重的点需要考虑,我们按权重顺序存,到时候排名次就按for的循环变量累加即可,如果不按这个顺序存,后期不好给学生成绩做一个排名,循环里面的代码不好写。
- 然后就是排名信息了,每个学生的ACME在总体中的排名,这个是最不好处理的,因为题目要求输出当前学生的最好排名,也就是说你得把每个学生的4门课的排名算出来,那有两种选择,一种是你在结构体中加入rank[4],一种是单独创建一个数组
rank[1000000][4]
。我选择的后者,横坐标就是id,纵坐标就是4门科目的排名,之所以选用后者是因为方便,然后不需要每一个都遍历,只需要按照下标来找对应的排名即可。
思路理清了,做这个题还有两个需要注意的点:
- 该排名必须是11345,不能是11234,其实这种很多题都是这样,解决办法也很固定,就是用for循环的循环变量来处理。
- 所有需要考虑权重的排序,我们的思路都是一样的,即无论是rank数组,还是grade数组,还是v数组,数组按顺序均表示ACME同一个含义,这样可以很好的处理在出现成绩相同需要考虑权重这一问题。
这个题的平均数不用四舍五入也是对的,但是还是养成一个好习惯,所以我用了round函数做处理
实现代码
#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
#include<cmath>
#include<sstream>
#include<algorithm>
#pragma warning(disable:4996)
using namespace std;
struct Student
{
int id;
int grade[4];
}Stu[2001];
char v[]={"ACME"};
int Rank[10000000][4];
int now;
//降序排列,分数高的在前面
bool cmp(Student a,Student b)
{
return a.grade[now]>b.grade[now];
}
int main()
{
#ifdef ONLINE_JUDGE
#else
freopen("1.txt", "r", stdin);
#endif
int n,m;
cin>>n>>m;
for(int i=0;i<n;i++)
{
cin>>Stu[i].id>>Stu[i].grade[1]>>Stu[i].grade[2]>>Stu[i].grade[3];
Stu[i].grade[0]=round((Stu[i].grade[1]+Stu[i].grade[2]+Stu[i].grade[3])/3);
}
for(now=0;now<4;now++)
{
sort(Stu,Stu+n,cmp);
Rank[Stu[0].id][now]=1;
for(int j=1 ; j<n ; ++j)
{
if(Stu[j].grade[now] == Stu[j-1].grade[now])
Rank[Stu[j].id][now]=Rank[Stu[j-1].id][now];
else
Rank[Stu[j].id][now]=j+1;
}
}
int temp;
for(int i=0;i<m;i++)
{
cin>>temp;
if(Rank[temp][0]==0)
{
cout<<"N/A"<<endl;
}
else
{
int x=0;
for(int j=0;j<4;j++)
{
if(Rank[temp][j]<Rank[temp][x])
{
x=j;
}
}
cout<<Rank[temp][x]<<" "<<v[x]<<endl;
}
}
return 0;
}
Comments | NOTHING