PAT 甲級測試題目 -- 1012 The Best Rank
阿新 • • 發佈:2019-01-20
的人 ref 0ms subject rank ems == ble str
由於要統計各類成績排名,而且時間限制在 200ms,所以我想用空間換時間,定義了四個數組分別存儲 C,M,E,A 四種類型的成績。
因為考慮到如果成績相同,則排名相同,下一個排名為上一個的排名加上人數。例如對於 A 類型分數,100分 的有 2 人,99 分的有 1 人,則 100 分的兩人排名均為 1,99 分的 1 人排名為 3。
所以對於存儲成績的四個數組,先存儲人數,然後根據人數更新排名。
最後遍歷的時候,對於每個學生的 vector,根據上述的四個數組確定最高的 排名 以及對應的 分數類型。
最多共需要 32000 + 100 + 42000 = 14100 次循環。
看了其他博主的解析,有用結構體實現的,不知道效率如何,我這邊的代碼跑了 16ms
題目鏈接
題目描述
輸入小於等於 2000 的數據 N,M,分別表示 學生的總數 和 查詢學生的數量
輸入 N 個學生的六位數 id 以及 C,M,E 三科成績。輸入 M 個查詢學生的 id。
要求輸出:
若被查詢的 id 不存在,輸出 N/A
若被查詢的 id 存在,輸出 C,M,E,A(average 平均分) 四個成績中排名最高的排名,以及對應的分數類型(C, M, E, A)。若有多余一個類型的分數相同,則按照 A > C > M > E 的優先序列輸出 排名 和 分數類型
分析
由於各類成績和學生 id 是對應關系,所以我想到使用 map<string, vector>類型存儲錄入的數據。
因為考慮到如果成績相同,則排名相同,下一個排名為上一個的排名加上人數。例如對於 A 類型分數,100分 的有 2 人,99 分的有 1 人,則 100 分的兩人排名均為 1,99 分的 1 人排名為 3。
所以對於存儲成績的四個數組,先存儲人數,然後根據人數更新排名。
最後遍歷的時候,對於每個學生的 vector,根據上述的四個數組確定最高的 排名 以及對應的 分數類型。
最多共需要 32000 + 100 + 42000 = 14100 次循環。
看了其他博主的解析,有用結構體實現的,不知道效率如何,我這邊的代碼跑了 16ms
實現
#include<iostream> #include<map> #include<vector> #include<string> #include<string.h> using namespace std; int main() { // 存儲學生總數 和 被檢查的學生數量 int total_students, checked_students; // 存儲輸入的學生信息,string 存儲姓名,vector 存儲成績 map<string, vector<int>> students; // 存儲 C, M, E, A 四門科目成績對應的人數,然後使用算法計算成績對應的排名 int C[101], M[101], E[101], A[101]; // 初始化 C, M, E, A 四門科目成績對應的人數為 0 memset(C, 0, sizeof(C)); memset(M, 0, sizeof(M)); memset(E, 0, sizeof(E)); memset(A, 0, sizeof(A)); // 存儲存儲學生總數 和 被檢查的學生數量 cin >> total_students >> checked_students; // 初始化學生信息 for (int i = 0; i < total_students; i++) { // 記錄學生的 id string student_id; // 記錄學生的成績 int grade, average = 0; vector<int> grades; // 輸入學生 id cin >> student_id; // 輸入學生成績 for (int j = 0; j < 3; j++) { cin >> grade; grades.push_back(grade); average += grade; // 記錄三科成績的人數 if (j == 0) C[grade]++; if (j == 1) M[grade]++; if (j == 2) E[grade]++; } // 記錄平均成績 A[average / 3]++; // 插入平均成績到最前面,方便按照題意中的優先級給出 rank grades.insert(grades.begin(), average / 3); // 插入學生信息 students.insert(pair<string, vector<int>>(student_id, grades)); } // 根據錄入的三科成績人數計算排名 int rankC, rankM, rankE, rankA; rankC = rankM = rankE = rankA = 1; // 用於交換數據 int temp; for (int i = 100; i >= 0; i--) { // 更新 C 排名 temp = C[i]; if (temp != 0) { C[i] = rankC; rankC += temp; } // 更新 M 排名 temp = M[i]; if (temp != 0) { M[i] = rankM; rankM += temp; } // 更新 E 排名 temp = E[i]; if (temp != 0) { E[i] = rankE; rankE += temp; } // 更新 A 排名 temp = A[i]; if (temp != 0) { A[i] = rankA; rankA += temp; } } // 查找學生成績 for (int i = 0; i < checked_students; i++) { // 記錄要查找的學生 id string id; cin >> id; // 如果找不到該學生 if (students.count(id) == 0) { cout << "N/A"; } // 如果找到了 else { // 定義 char 數組方便輸出科目 char subject[4] = { 'A', 'C', 'M', 'E' }; // 定義 int 變量方便輸出科目 int index, search_index = 0; // 記錄排名第一的科目以及科目的成績,記錄成績方便從成績表中查到排名 int topRank = 2001, rankGrade; // 叠代器遍歷 vector 容器,查詢對應學生的每個科目的成績 for (vector<int>::iterator iter = students[id].begin(); iter != students[id].end(); iter++) { // 記錄成績 rankGrade = *iter; // 對每個科目進行查找 if (search_index == 0) { if (topRank > A[rankGrade]) { topRank = A[rankGrade]; index = 0; } } if (search_index == 1) { if (topRank > C[rankGrade]) { topRank = C[rankGrade]; index = 1; } } if (search_index == 2) { if (topRank > M[rankGrade]) { topRank = M[rankGrade]; index = 2; } } if (search_index == 3) { if (topRank > E[rankGrade]) { topRank = E[rankGrade]; index = 3; } } // 查找下一個科目 search_index++; } cout << topRank << " " << subject[index]; } // 控制格式輸出 if (i != checked_students - 1) cout << endl; } return 0; }
希望能幫到大家!
PAT 甲級測試題目 -- 1012 The Best Rank