1012 The Best Rank (25 分)c++实现(已AC, 已重构)

题目:

链接:https://pintia.cn/problem-sets/994805342720868352/problems/994805502658068480

思路:

像是自己见一个数据库, 用以增和查, 我的思路是按照4个科目(M, C, E, A)建四个表, 每张表的内容为<姓名, 成绩>,这个表在类内用map维护, 成绩输入完成后, 做一张<姓名, 排名>表, 之后的查询直接返回值.实现过程中,在做第二张表时,遇到的主要问题是第一张表对应的map没法直接做按成绩排序.

坑点:

  1. 大坑警告!!! 如果两个孩子的成绩是并列的, 需要把他们处理成相同排名, 然后后面的小朋友跳过站位,例如 1, 2, 2, 4, 5
  2. stl::map 的按value排序并不是很好使
    首先,map的实现是key有序的, 也就是说直接遍历可以得到一个以key排序的map, 当然,在map的构造器中可以看到compare方法
    是可以给定的, 但是尝试后以失败告终,网上找到的资料都是对key用不同的方式排序, 没有对value的情况,stackoverflow上给
    出的方法是再用一个map把value作为key倒腾一下(仅限于value唯一存在的情况),成绩很可能会重合所以不能用惹, 另一个建议
    采用multimap, 这个我stl类我还没有学, 好像用的也不多, 所以暂时放一放, 最后的处理办法是再做一个vector把map里面的
    pair_type类型的数据都倒腾出来, 然后就可以用sort排序了,排序方法也可指定,这里用的是自己写的cmp_by_value
  3. 我感觉我的map数据结构选的很不好, 但是也没有尝试别的方法, 比如单独搞个数组,把ID和grade放进去排序,排完便利数组, 拿着
    数组元素读出来的id和当前index去填一个
    struct grade_information {
        m_grade
        e_grade
        c_grade
        a_grade
        m_rank
        c_rank
        a_rank
        e_rank
    }
    
    的结构,用map<string, grade_information>保存以供查询这样

代码

采用第二种思路的代码

#include<iostream>
#include<cstdio>
#include<cmath>
#include<map>
#include<algorithm>
using namespace std;
struct student {
    char id[8];
    short grade[4], rank[4];
}students[2005];
int n; // num of students
map<string, int> query_list;
char subjects[] = {'C', 'M', 'E', 'A'};
bool cmp_by_c(int i, int j) { return students[i].grade[0] > students[j].grade[0]; }
bool cmp_by_m(int i, int j) { return students[i].grade[1] > students[j].grade[1]; }
bool cmp_by_e(int i, int j) { return students[i].grade[2] > students[j].grade[2]; }
bool cmp_by_a(int i, int j) { return students[i].grade[3] > students[j].grade[3]; }

void mark_rank(int temp_rank[], int subject) {
    students[temp_rank[0]].rank[subject] = 1;
    for (int i = 1; i < n; i++) {
        if (students[temp_rank[i]].grade[subject] == students[temp_rank[i-1]].grade[subject])
            students[temp_rank[i]].rank[subject] = students[temp_rank[i-1]].rank[subject];
        else students[temp_rank[i]].rank[subject] = i + 1;
    }
}
void getrank(int subject) {
    int temp_rank[2005];
    for (int i = 0; i < n; i++) {
        temp_rank[i] = i;
    }
    bool (*cmp)(int, int);
    switch (subject) {
        case 0 : cmp = cmp_by_c;break;
        case 1 : cmp = cmp_by_m; break;
        case 2 : cmp = cmp_by_e; break;
        case 3 : cmp = cmp_by_a; 
    }
    sort(temp_rank, temp_rank+n, cmp);
    mark_rank(temp_rank, subject);
}

int main() {
    int m;
    scanf("%d%d", &n, &m);
    for (int i = 0; i < n; i++) {
        scanf("%s%d%d%d", students[i].id, &students[i].grade[0], &students[i].grade[1], &students[i].grade[2]);
        students[i].grade[3] = (int)round((students[i].grade[0] + students[i].grade[1] + students[i].grade[2]) * 1.0 / 3);
        query_list[students[i].id] = i;
    }
    for (int i = 0; i < 4; i++) getrank(i);
    while (m--) {
        //string temp_id;
        //cin >> temp_id;
        char temp_id[8];
        scanf("%s", temp_id);
        if (query_list.count(temp_id) == 0) printf("N/A\n");
        else {
            int index = query_list[temp_id], best_rank = n;
            char best_subject;
            for (int i = 3; i < 7; i++) {
                if (students[index].rank[i%4] < best_rank) {
                    best_rank = students[index].rank[i%4];
                    best_subject = subjects[i%4];
                }
            }
            printf("%d %c\n", best_rank, best_subject);
        }
    }
    return 0;    
}

原始代码

#include<iostream>
#include<cstdio>
#include<map>
#include<vector>
#include<algorithm>
using namespace std;

typedef pair<string, int> PAIR;
struct CmpByValue {  
  bool operator()(const PAIR& lhs, const PAIR& rhs) {  
    return lhs.second < rhs.second;  
  }  
}; // abondon because of unsolved error.

bool cmp_by_value(const PAIR& lhs, const PAIR& rhs) {  
  return lhs.second < rhs.second;  
}
// used for building a map sorted by values;

class Course {
    private:
    map<string, int> students;
    map<string, int> ranklist;
    string course_name;
    int count = 0;
    public:
    Course(string name) { course_name = name; }
    void insert(string id, int grade);
    int get_rank(string id);
    void update_rank();
    int getsize();
    string inline get_course_name() { return course_name; }
};



void getbestrank(string ID, int &best_rank, string &best_course, Course &course_name);

int main()
{
    Course C("C"), M("M"), E("E"), A("A");
    int n, m;
    cin >> n >> m;
    while (n--){
        string ID;
        int c_grade, m_grade, e_grade, a_grade;
        cin >> ID >> c_grade >> m_grade >> e_grade;
        a_grade = (c_grade + m_grade + e_grade) /3;
        C.insert(ID, c_grade);
        M.insert(ID, m_grade);
        E.insert(ID, e_grade);
        A.insert(ID, a_grade);
    }
    C.update_rank();
    M.update_rank();
    E.update_rank();
    A.update_rank();
    while(m--){
        string ID, best_course;
        cin >> ID;
        int best_rank = A.getsize();
        getbestrank(ID, best_rank, best_course, A);
        getbestrank(ID, best_rank, best_course, C);
        getbestrank(ID, best_rank, best_course, M);
        getbestrank(ID, best_rank, best_course, E);
        if (best_rank == -1)
            cout << "N/A" << endl;
        else
            cout << best_rank << " " << best_course << endl;
    }
    getchar();
    getchar();
    return 0;
}

void getbestrank(string ID, int &best_rank, string &best_course, Course &course_name)
{
    int cur_rank = course_name.get_rank(ID);
    if (cur_rank == -1) { // ID not on the list
        best_rank = -1; return; 
    }
    if (cur_rank < best_rank) {
        best_rank = cur_rank;
        best_course = course_name.get_course_name();
    }
}

void Course::insert(string id, int grade)
{
    students[id] = grade;
}

int Course::get_rank(string id)
{
    if (ranklist.count(id) == 0)
    return -1; // not on list
    else return ranklist[id];
}

void Course::update_rank()
{
    vector<pair<string, int>> temp(students.begin(), students.end());
    sort(temp.begin(), temp.end(), cmp_by_value);
    int i = 1;
    for(int j = temp.size() - 1; j >= 0; j--) {
        if ((j != temp.size() - 1 && temp[j].second < temp[j+1].second) || j == temp.size() - 1)
            ranklist[temp[j].first] = i++;
        else {
            ranklist[temp[j].first] = ranklist[temp[j+1].first];
            i++;
        }
    }
}
int Course::getsize() { return students.size(); }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值