PATbest ranking

最好排名

题目简介

要求输入学号,以及三科成绩;然后进行查询,输入学号,输出排名最好的一科的科目及排名。

大致思路

  1. 思路一:利用结构体的思路然后进行排序,这样可以进行id与成绩的相对应。但是需要开辟三个空间,然后在其中进行搜索。

  2. 思路二: 因为不需要成绩与id相互对应,只需要在成绩的这一栏中进行查询就可以知道他的排名。相同的成绩排名相同。因此只需要将成绩和id储存下来即可。

具体思路

  1. 要知道在无序的数据中,某个数据是否存在,要用到hash。利用stl标准库,unordered_map,进行操作。
  2. 然后需要对于三个成绩需要分别存储,因此用vectodr进行存储。并进行排序,方便进行比对。利用sort函数。
  3. 在进行名次的寻找的时候,可以进行遍历,也可以进行二分。在有序的数据中,显然二分的速度更快。

小细节

  1. 四舍五入的函数 round(double x) 在cmath库中。 int转化为double*1.0
  2. 在多次重复操作的时候,记得用for循环进行代替,会更为简洁。

需要复习的知识点

  1. stl库函数的使用 unordered_map的诸多灵活的使用
  2. 二分的掌握

代码

//
//  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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值