您的位置:首页 > 其它

10-排序5 PAT Judge   (25分)

2017-05-28 01:00 295 查看
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,
NN (≤10^4​​),
the total number of users, KK (≤5),
the total number of problems, and MM (≤10^5​​),
the total number of submissions. It is then assumed that the user id's are 5-digit numbers from 00001 to
NN, and the problem id's are from 1 to
KK. The next line contains
KK positive integers
p[i]
(
i
=1, ..., KK), where
p[i]
corresponds to the full mark of the i-th problem. Then
MMM
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-1−1if 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 thereis 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 solutio
bb34
n, 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 -


思路:用一个结构数组来存储所有的数据,根据总分score,完整解题数cnt,和id来排序这个结构数组的元素。

注意点:

1、按总分递减排序,如果总分相同,则按完整解题数递减排序,如果完整解题数也相同,则按id递增排序

2、只有一次都没提交过或者提交过但没有一题通过编译的用户不显示

3、如果一个用户会显示在排名表中,那么如果他提交的某题没有通过编译,则显示0;(也就是说,显示的用户,只有没提交过的题才显示' - ')

4、先记录每人每题的最高得分,并根据得分来判断用户是否显示;然后再计算总分和完整解题数;这样思路会比较清晰(每题的得分是接收得到的,是否显示用户与该题的得分直接相关,而总分和完整解题数又和最高得分直接相关)

5、相同总分的人名次是相同的。(因此需要用LastScore和LastRank来记住上一个人的分数与排名)

#include <stdio.h>
#include <stdlib.h>
struct User {int id, score, cnt, visited, problem[6];
}user[10005];int FullScore[5];int Cmp ( const void *a, const void *b ) {int k;if ( ((const struct User*)a)->score < ((const struct User*)b)->score ) //按分数递减排序
k = 1; //返回大于0,a,b位置需交换
else if ( ((const struct User*)a)->score > ((const struct User*)b)->score )
k = -1; //返回小于0, a,b位置不变
else {if ( ((const struct User*)a)->cnt < ((const struct User*)b)->cnt ) //按完整解题数量递减排序
k = 1;
else if ( ((const struct User*)a)->cnt > ((const struct User*)b)->cnt )
k = -1;
else {if ( ((const struct User*)a)->id < ((const struct User*)b)->id ) //按id递增排序;
k = -1;
else
k = 1;
}
}
return k;
}int main () {int N, K, M, Uid, Pid, Pscore;
scanf("%d%d%d", &N, &K, &M);
for ( int i = 0; i < K; i++ )
scanf("%d", &FullScore[i]);
//初始化结构数组
for ( int i = 0; i < N; i++ ) {
user[i].id = i + 1; //题中是从1开始
user[i].cnt = 0;
user[i].score = 0;
user[i].visited = 0;
for ( int j = 0; j < K; j++ )
user[i].problem[j] = -2; //实际最小-1
}
//接收分数并确定是否显示该用户
for ( int i = 0; i < M; i++ ) {
scanf("%d %d %d", &Uid, &Pid, &Pscore);if ( user[--Uid].problem[--Pid] < Pscore ) { //题中从1开始,这里从0开始if ( Pscore > -1 ) //通过1题或以上编译的用户会显示
user[Uid].visited = 1;
user[Uid].problem[Pid] = Pscore;
}
}
//计算总分和完整解题数
for ( int i = 0; i < N; i++ ) {
for ( int j = 0; j < K; j++ ) {if ( user[i].problem[j] > 0 ) {
user[i].score += user[i].problem[j]; //累计总分if ( user[i].problem[j] == FullScore[j] ) //记录完整解题数
user[i].cnt++;
}
}
}
//排序
qsort( user, N, sizeof(struct User), Cmp );
//输出int LastScore = user[0].score, LastRank = 1;
for ( int i = 0; i < N; i++ ) {if ( user[i].visited == 1 ) {if ( LastScore == user[i].score ) { //如果和上一个分数相同
printf("%d %05d %d", LastRank, user[i].id, LastScore);
}
else { //如果和上一个分数不同
LastScore = user[i].score; //更新上一个的分数
LastRank = i + 1; //更新上一个的排名
printf("%d %05d %d", i + 1, user[i].id, user[i].score);
}
for ( int j = 0; j < K; j++ ) {if ( user[i].problem[j] == -1 ) //将未通过编译的分数设为0
user[i].problem[j] = 0;if ( user[i].problem[j] >= 0 )
printf(" %d", user[i].problem[j]);
else
printf(" -");
}
printf("\n");
}
}
system("pause");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: