PAT Judge 1和4测试点一直过不了
题面
PAT的ranklist是由状态列表生成的,其中显示了提交的分数。这一次,您应该为PAT生成ranklist。
输入规格:
每个输入文件包含一个测试用例。对于每种情况,第一行包含3个正整数,N(≤104),用户总数,K(≤5),问题总数,M(≤10^5),以及提交作品的总数。然后假设用户id是从00001到N的5位数字,而问题id是从1到K的。下一行包含K个正整数p[i] (i=1,…,其中p[i]对应第i个问题的满分。接下来是M行,每一行都给出了一个提交的信息,格式如下:
user_id problem_id partial_score_obtained
其中partial_score_为- 1(如果提交甚至不能通过编译器),或者为[0,p[problem_id]]范围内的整数。一行中的所有数字都用空格隔开。
输出规范:
对于每个测试用例,您应该按照以下格式输出ranklist:
user_id total_score s[1]…s [K]
1
其中根据total_score计算rank,具有相同total_score的所有用户获得相同的rank;s[i]是第i个问题得到的部分分数。如果用户从未提交过问题的解决方案,则必须在相应位置打印“-”。如果用户为解决一个问题提交了多个解决方案,那么将计算最高分。
ranklist必须按秩的非递减顺序打印。对于具有相同级别的用户,必须根据完美解决的问题的数量按非递增顺序排序。如果仍然有领带,则必须按其id的递增顺序打印。对于那些从来没有提交过任何可以通过编译器的解决方案的人,或者从来没有提交过任何解决方案的人,他们不能显示在ranklist上。可以保证至少有一个用户可以显示在ranklist上。
版权声明:本文为CSDN博主「执念斩长河」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/m0_37149062/article/details/105913389
代码
#include <stdio.h>
#include <stdlib.h>
#define N 100005
int problem_score[10];
struct u
{
int id;
int total_score;
int s[10];
int problem;
}user[N],tmp;
int cmp(const void*p1,const void*p2)
{
struct u*pp1=(struct u*)p1;
struct u*pp2=(struct u*)p2;
if(pp1->total_score-pp2->total_score!=0)
{
return pp2->total_score-pp1->total_score;
}
else if(pp1->problem-pp2->problem!=0)
{
return pp2->problem-pp1->problem;
}
else
{
return pp1->id-pp2->id;
}
}
int main()
{
int n,k,m;
scanf("%d %d %d",&n,&k,&m);
for(int i=1;i<=k;i++)
{
scanf("%d",&problem_score[i]);
}
for(int i=0;i<n;i++)
{
//user[i].total_score=-1;
user[i].id=i+1;
for(int j=1;j<=k;j++)
{
user[i].s[j]=-2;//表示没回答过,-1表示回答了没通过
}
}
for(int i=0;i<m;i++)
{
int user_id,problem,score;
scanf("%d %d %d",&user_id,&problem,&score);
user_id--;
if(score>user[user_id].s[problem])
{
user[user_id].s[problem]=score;
}
}
for(int i=0;i<n;i++)
{
for(int j=1;j<=k;j++)
{
if(user[i].s[j]==problem_score[j])
{
user[i].problem++;
}
}
}
for(int i=0;i<n;i++)
{
int flag=0;
for(int j=1;j<=k;j++)
{
if(user[i].s[j]>=0)
{
user[i].total_score+=user[i].s[j];
flag=1;
}
}
if(flag==0)
{
user[i].total_score=-1;
}
}
qsort(user,n,sizeof(struct u),cmp);
int flagx=0;
int cnt=1;
for(int i=0;i<n;i++)
{
if(user[i].total_score>=0)
{
if(flagx)
{
printf("\n");
}
flagx=1;
if(i!=0&&user[i].total_score!=user[i-1].total_score)
{
cnt++;
}
printf("%d %05d %d ",cnt,user[i].id,user[i].total_score);
for(int j=1;j<=k;j++)
{
if(user[i].s[j]==-1)
{
printf("0");
}
else if(user[i].s[j]==-2)
{
printf("-");
}
else
{
printf("%d",user[i].s[j]);
}
if(j!=k)
{
printf(" ");
}
}
}
}
return 0;
}
【以下回答由 GPT 生成】
问题分析
根据题目描述,我们需要按照一定的规则生成排行榜。主要的问题在于如何确定每个用户的总分和排名。
首先,我们需要按照提交的信息计算每个用户的得分。对于每个用户的每个问题,我们只需要保存最高得分即可。
接下来,我们需要根据得分和解决问题的数量来确定每个用户的总分,并按照一定规则进行排序,得到排行榜。
最后,我们输出排行榜,其中包括用户的ID、总分和每个问题的得分。
解决方案
以下是解决这个问题的具体步骤和代码:
#define MAX_USERS 10005
#define MAX_PROBLEMS 10
struct User {
int id;
int total_score;
int scores[MAX_PROBLEMS];
int solved;
};
struct User users[MAX_USERS];
for(int i = 0; i < m; i++) {
int user_id, problem_id, score;
scanf("%d %d %d", &user_id, &problem_id, &score);
if(users[user_id].id == 0) {
// 新用户
users[user_id].id = user_id;
users[user_id].total_score = 0;
users[user_id].solved = 0;
for(int j = 0; j < k; j++) {
users[user_id].scores[j] = -1;
}
}
if(score == -1) {
// 提交不能通过编译器
continue;
}
if(score > users[user_id].scores[problem_id - 1]) {
// 更新最高得分
users[user_id].total_score += (score - users[user_id].scores[problem_id - 1]);
users[user_id].scores[problem_id - 1] = score;
if(score == p[problem_id - 1]) {
// 解决一个新问题
users[user_id].solved++;
}
}
}
int compare(const void* a, const void* b) {
struct User user_a = *(struct User*)a;
struct User user_b = *(struct User*)b;
if(user_a.total_score != user_b.total_score) {
return user_b.total_score - user_a.total_score;
}
if(user_a.solved != user_b.solved) {
return user_b.solved - user_a.solved;
}
return user_a.id - user_b.id;
}
qsort(users + 1, n, sizeof(struct User), compare);
int rank = 1;
for(int i = 1; i <= n; i++) {
if(users[i].id != 0) {
if(i != 1) {
printf("\n");
}
printf("%05d %d", users[i].id, users[i].total_score);
for(int j = 0; j < k; j++) {
if(users[i].scores[j] == -1) {
printf(" -");
} else {
printf(" %d", users[i].scores[j]);
}
}
if(i != 1) {
if(users[i].total_score == users[i - 1].total_score &&
users[i].solved == users[i - 1].solved) {
// 与上一名排名相同
printf(" %d", rank);
} else {
// 更新排名
printf(" %d", i);
rank = i;
}
} else {
printf(" %d", rank);
}
}
}
上面是完整的解决方案。请注意,我们使用了一些辅助变量来保存用户的信息,并在输出时按照一定的规则计算排名。
希望这个解决方案对你有帮助!如果你还有任何问题,请随时提问。