-
题目大意:根据提交的状态列表,生成PAT的排名列表。
-
若提交不成功,显示为为-1,实际得分为0;若提交成功,显示为[0, p[pid]]。(注意:若用户提交成功但是没编译通过,虽然显示的是-1,但要把分数赋值为0。我之前读错题了,以为得分是-1)。
-
结果按总分排名,若总分相同则排名相同。排名和id后面跟着各题的分数(未提交为’-’,提交多次为最高分)。
-
输出按排名升序。若排名相同,就按满分题目的个数降序排。若还相同,就按id升序排。
-
没提交成功过或没有提交过的人不进行排名(即成绩为-1均为或没提交过题目的人)。注意:保证排名列表里最少有一个人。
-
-
思路:用结构体存储用户的信息,然后进行排序。
-
用flag记录该用户是否提交过可通过的答案。将每个人的各题的成绩初始化为0,总成绩都初始化为-1(因为还要考虑只有一个学生,且总分为0的情况)。每次输入成绩时,都比较大小,若比原有成绩大,就更新成绩。(注意:因为若用户提交成功但是没编译通过,虽然显示的是-1,但要把分数赋值为0)
-
得分数组应该先初始化为-1,-1未编译成功或者没提交过的题目。
-
结构体里记录满分题的个数,方便后面排序,之后还需在一个循环里统计满分提的个数
-
输出按排名升序,即按总分降序。若总分相同,就按满分题目的个数降序排。若还相同,就按id升序排。
遇到flag为false的跳过。
-
-
知识点:
- 结构体
- vector
- sort
-
代码:
#include <iostream> #include <vector> #include <algorithm> using namespace std; struct user{ bool flag = false; int id, total = -1, cnt = 0; // cnt记录满分题的个数 int p[6] = {-1, -1, -1, -1, -1, -1}; //数组记录该用户每题的得分 }; int count(user u, int k, int* p){ int cnt = 0; for(int i = 1; i <= k; i++) // 注意i从1开始 if(u.p[i] == p[i]) cnt++; return cnt; } int sumScore(user u, int k){ int sum = 0, cnt = 0; // cnt记录未通过/没做过的题目个数 for(int i = 1; i <= k; i++) // 注意i从1开始 if(u.p[i] != -1) sum += u.p[i]; else cnt++; if(cnt == k) sum = -1; return sum; } bool cmp(user a, user b){ if(a.total != b.total) return a.total > b.total; else{ return a.cnt != b.cnt ? a.cnt > b.cnt : a.id < b.id; } } int main() { int n, k, m; scanf("%d %d %d", &n, &k, &m); int p[6] = {0}; vector<user> v(10001); // user temp; for(int i = 1; i <= k; i++) // 注意题目id是从1开始的 scanf("%d", p + i); // 将id、各题分数、总分输入user数组 for(int i = 0; i < m; i++){ int id, index, score; scanf("%d %d %d", &id, &index, &score); v[id].id = id; if(score != -1) v[id].flag = true; if(score == -1 && v[id].p[index] == -1) v[id].p[index] = 0; else if(score > v[id].p[index]) v[id].p[index] = score; } // 统计每个用户满分题的个数和总分 for(int i = 1; i <= n; i++){ v[i].cnt = count(v[i], k, p); v[i].total = sumScore(v[i], k); } sort(v.begin(), v.end(), cmp); int rank = 0, temp_rank = 0, total = -1; // 注意total初始化为-1, for(int i = 0; i < n; i++){ if(v[i].flag == false) continue; else{ rank++; if(v[i].total != total){ total = v[i].total; temp_rank = rank; } printf("%d %05d %d", temp_rank, v[i].id, v[i].total); for(int j = 1; j <= k; j++){ if(v[i].p[j] == -1) printf(" -"); else printf(" %d", v[i].p[j]); } printf("\n"); } } return 0; }
-
总结:
- 可以用一个bool变量flag记录用户是否提交过代码或编译成功过代码,这样就可以在输出时判断是否要输出该用户信息。
- 粗心:
- 读题不仔细:
- 注意题目id和用户id都是从1开始的;
- 若用户提交成功但是没编译通过,虽然显示的是-1,但要把分数赋值为0;
- “It is guaranteed that at least one user can be shown on the ranklist.” 表示还要考虑只有一个用户,但得分全是0的情况。要把total初始化为-1。
- 读题不仔细:
【PAT】1075 PAT Judge (25 分)
最新推荐文章于 2022-04-21 16:11:40 发布
![](https://img-home.csdnimg.cn/images/20240711042549.png)