PATA1075 PAT Judge (25 分)
The ranklist of PAT is generated from the status list, which shows the scores of the submissions. This time you are supposed to generate the ranklist for PAT.
Input Specification:
Each input file contains one test case. For each case, the first line contains 3 positive integers, N (≤10^4), the total number of users, K (≤5), the total number of problems, and M (≤10^5 ), the total number of submissions. It is then assumed that the user id's are 5-digit numbers from 00001 to N, and the problem id's are from 1 to K. The next line contains K positive integers p[i] (i=1, ..., K), where p[i] corresponds to the full mark of the i-th problem. Then M lines follow, each gives the information of a submission in the following format:
user_id problem_id partial_score_obtained
where partial_score_obtained is either −1 if the submission cannot even pass the compiler, or is an integer in the range [0, p[problem_id]]. All the numbers in a line are separated by a space.
Output Specification:
For each test case, you are supposed to output the ranklist in the following format:
rank user_id total_score s[1] ... s[K]
where rank is calculated according to the total_score, and all the users with the same total_score obtain the same rank; and s[i] is the partial score obtained for the i-th problem. If a user has never submitted a solution for a problem, then "-" must be printed at the corresponding position. If a user has submitted several solutions to solve one problem, then the highest score will be counted.
The ranklist must be printed in non-decreasing order of the ranks. For those who have the same rank, users must be sorted in nonincreasing order according to the number of perfectly solved problems. And if there is still a tie, then they must be printed in increasing order of their id's. For those who has never submitted any solution that can pass the compiler, or has never submitted any solution, they must NOT be shown on the ranklist. It is guaranteed that at least one user can be shown on the ranklist.
Sample Input:
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
Sample Output:
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 -
开始技术总结
开始自己想了很久没有没有思路,一个是先用一个结构体存储每一条记录然后再,使用一个结构体存储每一个学员的信息,但是其实这没有必要因为可以在读入的时候就把信息给处理掉
然后还有就是接下来不知道怎么处理了,一个是初始化问题,其实可以初始化id号从1开始,不用担心中间出现跳号的情况。
- 排序问题,题目中给出了三种优先级排序,总分,满分的题目数,id号从小往大排。
- 然后就是如果都是没有通过编译的或则没有提交的,不用输出。
- 合适的结构体,包含id,flag是否具备输出资格,sum总分,solve满分题目数量,score数组,存储每一个题目的分数,初始化为-1,如果要输出那么这个未通过编译的分数要变成0,题目中没有发现,但是样例中是这样体现的。
- 学会使用全局变量,这样其他函数可以使用这个变量。
- 学会初始化。
- 使用了memset函数初始化score数组。
- 输出打印使用了
printf("%05d", n);表示可以前面补0输出
参考代码:
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;
const int MAX_N = 10010;//学生最多10000人
//用于记录每个学生的具体情况
struct Student {
int id;//用户id
int sum;//记录总分
int score[6];//记录每个题目的得分情况
bool flag;//是否能有通过编译
int solve;//完美解题数
}stu[MAX_N];
int N, K, M;//使用全局变量,使得可以在外面的函数也可以使用该变量
int full_score[6];//每一题的满分是多少
//比较函数
bool cmp(Student a, Student b) {
if (a.sum != b.sum) return a.sum > b.sum;
else if (a.solve != b.solve) return a.solve > b.solve;
else return a.id < b.id;
}
//初始化
void init() {
for (int i = 1; i <= N; i++) {
stu[i].id = i;//id号记为i后面的输出可以,直接通过输出格式也行
stu[i].sum = 0;//初始化分数为0
stu[i].flag = false;
stu[i].solve = 0;//完美解决问题的数量也是初始化0
memset(stu[i].score, -1, sizeof(stu[i].score));//题目得分记为-1
}
}
int main() {
scanf("%d%d%d", &N, &K, &M);
init();
for (int i = 1; i <= K; i++) {
scanf("%d", &full_score[i]);
}
int u_id, p_id, p_score;//每条记录的学生id和提交每个题目的分数和题目id
for (int i = 0; i < M; i++) {
scanf("%d%d%d", &u_id, &p_id, &p_score);
if (p_score != -1) {//如果存在通过编译的就可以输出
stu[u_id].flag = true;
}
if (p_score == -1 && stu[u_id].score[p_id] == -1) {
//如果第一编译没有通过,分值记录0分方便输出
stu[u_id].score[p_id] = 0;
}
//如果某题第一次获的满分,那么完美解的次数加一次
if (p_score == full_score[p_id] && stu[u_id].score[p_id] < full_score[p_id]) {
stu[u_id].solve += 1;
}
if (stu[u_id].score[p_id] < p_score) {
//如果某题获得更高的分数,就替代
stu[u_id].score[p_id] = p_score;
}
}
//计算总分
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= K; j++) {
if (stu[i].score[j] != -1) {
stu[i].sum += stu[i].score[j];
}
}
}
sort(stu + 1, stu + N + 1, cmp);
int r = 1;//当前排名
for (int i = 1; i <= N && stu[i].flag == true; i++) {
if (i > 1 && stu[i].sum != stu[i - 1].sum) {
//当前考生分数低于之前考生分数的话,排名为自己序号,否则跟前一考生具有相同的排名
r = i;
}
printf("%d %05d %d", r, stu[i].id, stu[i].sum);
for (int j = 1; j <= K; j++) {
if (stu[i].score[j] != -1) {
printf(" %d", stu[i].score[j]);
}
else
{
printf(" -");//没提交过
}
}
printf("\n");
}
system("pause");
return 0;
}