PAT 的排名列表是根据状态列表产生的,状态列表中显示了所有提交记录的分数。
现在,请你为 PAT 生成排名列表。
输入格式
第一行包含三个整数 N,K,MN,K,M,分别表示总用户数量,题目数量,以及提交数量。
用户编号是从 0000100001 到 NN 的 55 位数字。
问题编号从 11 到 KK。
第二行包含 KK 个整数 p1,p2,…,pKp1,p2,…,pK,其中 pipi 表示第 ii 题的满分。
接下来 MM 行,每行包含一个提交信息,包括用户编号,题目编号,以及得分。
当提交无法正确编译时,得分显示 −1−1,否则是一个 [0,该题满分][0,该题满分] 范围内的整数。
注意,无法编译的情况虽然显示 −1−1,但得分上算作 00 分。
输出格式
以下列格式输出排名列表:
rank user_id total_score s[1] … s[K]
其中,rank 是根据 total_score 计算的,所以拥有相同 total_score 的用户的 rank 也相同。
s[i] 是第 ii 个问题获得的分数。
如果某个问题,用户从未提交过代码,则用 - 来表示这道题的分数。
如果某个问题,用户多次提交过代码,则取最高分为这道题的分数。
列表必须根据排名从前到后输出,对于排名相同的用户,根据满分题目的数量以降序对用户排序,如果仍有排名相同的情况,则按 ID 升序的顺序排序。
对于从未提交过任何代码,或者从未提交过任何编译通过的代码的用户,输出时不予考虑。
数据范围
1≤N≤1041≤N≤104,
1≤K≤51≤K≤5,
1≤M≤1051≤M≤105
每道题的满分为不超过 3030。
输入样例:
7 4 20
20 25 25 30
00002 2 12
00007 4 17
00005 1 19
00007 2 25
00005 1 20
00002 2 2
00005 1 15
00001 1 18
00004 3 25
00002 2 25
00005 3 22
00006 4 -1
00001 2 18
00002 1 20
00004 1 15
00002 4 18
00001 3 4
00001 4 2
00005 2 -1
00004 2 0
输出样例:
1 00002 63 20 25 - 18
2 00005 42 20 0 22 -
2 00007 42 - 25 - 17
2 00001 42 18 18 4 2
5 00004 40 15 0 25 -
#include <iostream>
#include <algorithm>
#include <unordered_map>
#include <vector>
using namespace std;
const int K = 6;
int n, k, m;
int p_score[K];
struct Student
{
string id;
int grade[K];
int total=0, cnt=0;
Student(){}
Student(string _id) : id(_id)
{
for (int i = 1; i <= k; i ++ ) grade[i] = -2;//-2是从来没有提交过或者没有通过编译
}
void calc()
{
for (int i = 1; i <= k; i ++ )
{
total += max(0, grade[i]);
if (grade[i] == p_score[i]) cnt ++ ;
}
}
bool has_submit() //判断是否要输出
{
for (int i = 1; i <= k; i ++ )
if (grade[i] >= 0)
return true;
return false;
}
bool operator< (const Student& t) const
{
if (total != t.total) return total > t.total;
if (cnt != t.cnt) return cnt > t.cnt;
return id < t.id;
}
};
int main()
{
unordered_map<string, Student> students; //一个编号对应一个学生
scanf("%d%d%d", &n, &k, &m);
for (int i = 1; i <= k; i ++ ) scanf("%d", &p_score[i]);
while (m -- )
{
string u_id;
char u_id_s[6];
int p_id, grade;
scanf("%s%d%d", u_id_s, &p_id, &grade);
u_id = u_id_s;
if (students.count(u_id) == 0) students[u_id] = Student(u_id);
students[u_id].grade[p_id] = max(students[u_id].grade[p_id], grade);
}
vector<Student> res;
unordered_map<string, Student>::iterator it;
for (it=students.begin();it!=students.end();it++)
{
Student s = (*it).second;
if (s.has_submit())
{
s.calc();
res.push_back(s);
}
}
sort(res.begin(), res.end());
for (int i = 0, rank = 1; i < res.size(); i ++ )
{
if (i && res[i].total != res[i - 1].total) rank = i + 1;
printf("%d %s %d", rank, res[i].id.c_str(), res[i].total);
for (int j = 1; j <= k; j ++ )
if (res[i].grade[j] == -2) printf(" -");
else printf(" %d", max(0, res[i].grade[j]));
puts("");
}
return 0;
}
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct node {
int rank, id, total = 0;
vector<int> score;
int passnum = 0;
bool isshown = false;
};
bool cmp1(node a, node b) {
if(a.total != b.total)
return a.total > b.total;
else if(a.passnum != b.passnum)
return a.passnum > b.passnum;
else
return a.id < b.id;
}
int main() {
int n, k, m, id, num, score;
scanf("%d %d %d", &n, &k, &m);
vector<node> v(n + 1);
for(int i = 1; i <= n; i++)
v[i].score.resize(k + 1, -2);
vector<int> full(k + 1);
for(int i = 1; i <= k; i++)
scanf("%d", &full[i]);
for(int i = 0; i < m; i++) {
scanf("%d %d %d", &id, &num, &score);
v[id].id = id;
v[id].score[num] = max(v[id].score[num], score);
if(score != -1)
v[id].isshown = true;
}
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= k; j++) {
if(v[i].score[j] != -1 && v[i].score[j] != -2)
v[i].total += v[i].score[j];
if(v[i].score[j] == full[j])
v[i].passnum++;
}
}
sort(v.begin() + 1, v.end(), cmp1);
for(int i = 1; i <= n; i++) {
v[i].rank = i;
if(i != 1 && v[i].total == v[i - 1].total)
v[i].rank = v[i - 1].rank;
}
for(int i = 1; i <= n; i++) {
if(v[i].isshown == true) {
printf("%d %05d %d", v[i].rank, v[i].id, v[i].total);
for(int j = 1; j <= k; j++) {
if(v[i].score[j]>=0)
printf(" %d", v[i].score[j]);
else if(v[i].score[j] == -2)
printf(" -");
else
printf(" 0");//没通过编译但是提交过
}
printf("\n");
}
}
return 0;
}