1. 程式人生 > >1012 The Best Rank (25 分)c++實現(已AC)

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<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(); }