最好排名
题目简介
要求输入学号,以及三科成绩;然后进行查询,输入学号,输出排名最好的一科的科目及排名。
大致思路
-
思路一:利用结构体的思路然后进行排序,这样可以进行id与成绩的相对应。但是需要开辟三个空间,然后在其中进行搜索。
-
思路二: 因为不需要成绩与id相互对应,只需要在成绩的这一栏中进行查询就可以知道他的排名。相同的成绩排名相同。因此只需要将成绩和id储存下来即可。
具体思路
- 要知道在无序的数据中,某个数据是否存在,要用到hash。利用stl标准库,unordered_map,进行操作。
- 然后需要对于三个成绩需要分别存储,因此用vectodr进行存储。并进行排序,方便进行比对。利用sort函数。
- 在进行名次的寻找的时候,可以进行遍历,也可以进行二分。在有序的数据中,显然二分的速度更快。
小细节
- 四舍五入的函数 round(double x) 在cmath库中。 int转化为double*1.0
- 在多次重复操作的时候,记得用for循环进行代替,会更为简洁。
需要复习的知识点
- stl库函数的使用 unordered_map的诸多灵活的使用
- 二分的掌握
代码
//
// main.cpp
// PAT_yxc_best_ranking
//
// Created by wonderful on 23/07/2021.
//
//这道题有个相对比较巧妙的地方。不适用结构体,可以直接根据成绩在列表里进行查询。
#include <iostream>
#include <unordered_map>
#include <vector>
#include <cmath>//用于进行四舍五入 round()
#include <algorithm>
using namespace std;
//unordered_map<string, int> students;//这个地方也有问题,主要需要用vector进行存储,如果单纯的int的话,只有一个value
unordered_map<string, vector<int >> grades;
vector<int> q[4];//用于存储a,c,m,e 四个成绩。是一个vector的数组
//进行二分
int get(vector<int> &a, int x)
{
int l = 0,r = a.size()-1;
while (l<r) {
int mid = l + r +1 >>1;
if (a[mid]<=x) l=mid;
else r=mid-1;
}
return a.size()-r;
}
int main(int argc, const char * argv[]) {
// insert code here...
int n,m;
cin>>n>>m;
for (int i=0; i<n; i++) {
string id;
int a,c,m,e;
cin>>id>>c>>m>>e;
a = round((c+m+e)/3.0);//小技巧,是除以3.0,将其转化为double类型
q[0].push_back(a);
q[1].push_back(c);
q[2].push_back(m);
q[3].push_back(e);
grades[id].push_back(a);
grades[id].push_back(c);
grades[id].push_back(m);
grades[id].push_back(e);
// 这个grades[id]的使用好灵活。
}
for (int i=0; i<4; i++) {
sort(q[i].begin(), q[i].end());
}
//又是一个小技巧,遍历的时候,如何将acme与数字相对应。可以建立一个字符串数组
char names[] = "ACME";
while (m--) {
string tmpid;
cin>>tmpid;
if (grades.count(tmpid)==0)cout<<"N/A"<<endl;
else
{
int res = n+1;
char c;
for (int i=0; i<4; i++)
{
int rank = get(q[i],grades[tmpid][i]);
if (rank<res) {
res = rank;
c = names[i];
}
}
cout<<res<<' '<<c<<endl;
}
}
//利用二分的方法,在有序的数据里面进行寻找,遍历的方式太耗时间。
return 0;
}