题目粗心:
有 N
位考生,其准考证号 00001~N
。共有K
道题,编号为 1~ K
, 且每道题的分值给出。而后给出 M 次提交记录,
每个提交记录显示了该次提交所属考生的准考证号、交题的题号及所得的分值,其中分值要么是 -1 (示意未通过编译),
要么是 0 到该题满分区间的一一个整数。
当初要求对所有考生按上面的 规定排序:
- 先按 K 道题所得总分从高到低排序。
- 若总分雷同,则按完满解决 (即取得题目满分) 的题目数量从高到低排序。
- 若完满解决的题目数量也雷同,则按准考证号从小到大排序。
算法思路:
首先得设计好存储信息的构造,对于输出,要记录考生的 id
,题目编号和对于的分数,对于输入来说,须要取得考生的排名,总分,每一道题的最高得分。为此应用构造体Student
保留考生的 id, 排名,总分,每一道题的最高得分及其是否提交状况,完满解题数和是否有编译通过的提交状况(简略了解就是是否须要输入)。而后就是对于每一条提交记录的分数的解决,解决规定如下:
- 对于每一条记录,记录其考生的
user_id
和problem_id
的提交状况(students[user_id].isSubmited[problem_id] = true;)
- 判断该题的得分
partial_score_obtained
是否为 -1, 如果不是 - 1 阐明为通过编译的提交,将students[user_id].hasSolution
置为true
,表明该用户存在通过编译的提交须要输入,而后判断该分数是否比现有的得分更高,如果是则更新最高分(students[user_id].s[problem_id] = partial_score_obtained;)
并且判断该最高分是否为满分,如果是则将完满解题数加一(++students[user_id].perfect;)
, 如果是 - 1 不必做其余解决,因为每一道题的得分曾经默认为 0,无需再置为 0 分接下来就是初始化总分,排序,获取排名,最初输入信息即可。
排序规定:
因为存在不须要输入的考生,然而这里对所有考生都进行了排序,所以得将无需输入的人放在前面。也即是 hasSolution
不同的考生,依据 hasSolution
从高到低排序,再而后根据上述的排序规定排序。也能够采纳遍历所有考生,将无需输入的考生剔除的形式来进行解决。
输入规定:
只输入 hasSolution
为true
的考生,对于这些考生如果 problem_id
的题目 isSubmited[problem_id]
为true
, 就输入分数(默认为 0,对应编译不通过的状况),否则就输入 ”-“
提交后果:
第一次测试:测试点 4 谬误。
第二次测试:全副正确。
留神点:
hasSolution==false
, 示意该用户没有提交一个可通过编译的答案,不必输入该用户的信息。hasSolution==true
, 阐明该用户至多有一个通过编译的提交,如果isSubmited[problem_id]==false
阐明该题没有提交输入 ”-“, 否则输入 0- 对于
hasSolution==false
的用户不参加排序。 - 对于测试点 4 考查的点次要在两个中央。第一个就是当一个用户反复提交满分代码的时候,完满解题数目不再重复记录,这里采纳了在呈现更高分的时候判断是否为满分在解决这个问题。第二个是以后记录的题目分数为 -1,然而之前有通过编译的提交也不要进行解决,放弃之前的记录即可,这里通过
isSubmited
数组进行的解决,无需进行记录编译出错的分数为 0,因为默认分数就是 0,所以只需记录通过编译的状况下的分数。 - 测试点 4 尽管考查的状况次要是以上 2 个状况,然而仍然会呈现思考了以上 2 种状况仍然出错的时候(比方自己(╥╯^╰╥)),这种次要是本人的代码逻辑出错,在这里记录两种情景。
出错情景一:
排序的时候将不该输入的人进行了排序,没有一道通过编译提交的人的总分为 0,有通过编译的提交然而全副谬误的人也是 0,当前者编号较小的时候,就会取得后者原本应该有的排名。
出错情景二:
如果在一个用户的所有提交记录中,某一道题只提交了一次,并且在其提交记录中排在第一个地位,并且提交为 -1,然而其余题目都是通过了编译的,那么依照自己的错误代码的写法就会导致没有通过编译的题目输入 ”-“, 而正确的输入是 0,因为该用户对该题有提交。
情景二的错误代码:
if (partial_score_obtained==-1&&students[user_id].hasSolution){
// 对于用户有其余通过编译的提交,对于本题没有通过编译,输入为 0,只有没有提交记录才是 "-"
students[user_id].isSubmited[problem_id] = true;
}
if (partial_score_obtained!=-1){
// 阐明有通过编译的提交
students[user_id].hasSolution = true;
students[user_id].isSubmited[problem_id] = true;
if (partial_score_obtained>students[user_id].s[problem_id]){
// 记录更高得分
students[user_id].s[problem_id] = partial_score_obtained;
// 更高得分为满分的时候完满解题数目加一
if (partial_score_obtained==p[problem_id]){++students[user_id].perfect;
}
}
}
谬误起因 :isSubmited
的作用是记录题目有没有提交,而错误代码的写法增加了判断条件,使其语义含糊,实属不该。
改过后的代码:
改过后的代码:students[user_id].isSubmited[problem_id] = true;
if (partial_score_obtained!=-1){
// 阐明有通过编译的提交
students[user_id].hasSolution = true;
if (partial_score_obtained>students[user_id].s[problem_id]){
// 记录更高得分
students[user_id].s[problem_id] = partial_score_obtained;
// 更高得分为满分的时候完满解题数目加一
if (partial_score_obtained==p[problem_id]){++students[user_id].perfect;
}
}
}
总结:
此题的细节解决较多,对于题目没有说分明的点,须要通过样例数据进行揣测验证,自己第一次写的时候也是各种踩坑,不过对于集体的逻辑解决能力有较大的帮忙。
AC 代码:
#include<cstdio>
#include<vector>
#include<unordered_map>
#include<algorithm>
#include<string>
using namespace std;
int p[6];// 每道题的满分
struct Student{
int user_id;
int rank; // 排名
int total_score; // 总分
int s[6]; // 记录每一道题的得分
bool isSubmited[6]; // 记录题目有没有提交
int perfect; // 完满解题数目
bool hasSolution; // 记录是否有解决方案提交,没有的不要输入该用户信息
}students[10010];
bool cmp(Student a,Student b){if(a.hasSolution!=b.hasSolution){return a.hasSolution>b.hasSolution;} else if (a.total_score!=b.total_score){return a.total_score>b.total_score;} else if (a.perfect!=b.perfect){return a.perfect>b.perfect;} else {return a.user_id<b.user_id;}
}
int main(){
int N,K,M;// 考生人数,问题数目,提交数目
scanf("%d %d %d",&N,&K,&M);
for (int i = 1; i <= K; ++i) {scanf("%d",&p[i]);
}
int user_id,problem_id,partial_score_obtained;
for (int j = 0; j < M; ++j) {scanf("%d %d %d",&user_id,&problem_id,&partial_score_obtained);
students[user_id].user_id = user_id;// 记录用户 id
students[user_id].isSubmited[problem_id] = true;// 记录 user_id 用户 problem_id 题目有提交
if (partial_score_obtained!=-1){
// 阐明有通过编译的提交
students[user_id].hasSolution = true; // 记录该用户存在可通过编译的提交,阐明须要输入
if (partial_score_obtained>students[user_id].s[problem_id]){
// 记录更高得分
students[user_id].s[problem_id] = partial_score_obtained;
// 更高得分为满分的时候完满解题数目加一
if (partial_score_obtained==p[problem_id]){++students[user_id].perfect;
}
}
}
}
// 初始化总分
for (int k = 1; k <= N; ++k) {for (int i = 1; i <= K; ++i) {students[k].total_score += students[k].s[i];
}
}
// 排序
sort(students+1,students+1+N,cmp);
// 获取排名
for (int l = 1; l <= N; ++l) {if (l==1){students[l].rank = 1;
} else if (students[l].total_score==students[l-1].total_score){students[l].rank = students[l-1].rank;
} else {students[l].rank = l;
}
}
// 输入信息
for (int m = 1; m <= N; ++m) {
// 只输入须要输入的用户信息
if (students[m].hasSolution) {printf("%d %05d %d", students[m].rank, students[m].user_id, students[m].total_score);
for (int i = 1; i <= K; ++i) {if (!students[m].isSubmited[i]) {
// 该题目没有提交记录
printf("-");
} else {printf("%d", students[m].s[i]);
}
}
printf("\n");
}
}
return 0;
}