版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m0_37407587/article/details/83547132
题目:
链接:https://pintia.cn/problem-sets/994805342720868352/problems/994805502658068480
思路:
像是自己见一个数据库, 用以增和查, 我的思路是按照4个科目(M, C, E, A)建四个表, 每张表的内容为<姓名, 成绩>,这个表在类内用map维护, 成绩输入完成后, 做一张<姓名, 排名>表, 之后的查询直接返回值.实现过程中,在做第二张表时,遇到的主要问题是第一张表对应的map没法直接做按成绩排序.
坑点:
- 大坑警告!!! 如果两个孩子的成绩是并列的, 需要把他们处理成相同排名, 然后后面的小朋友跳过站位,例如 1, 2, 2, 4, 5
- 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 - 我感觉我的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<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(); }