浙江大学数据结构MOOC-课后习题-第十讲-排序5 PAT Judge【未完成】

题目汇总
浙江大学数据结构MOOC-课后习题-拼题A-代码分享-2024

题目描述

这段文字是关于如何生成PAT(一种编程能力测试)的排行榜的说明。下面是这段文字的中文翻译:

输入说明:
每个输入文件包含一个测试案例。对于每个案例,第一行包含三个正整数,N(不超过10^4) ,表示用户总数;K(不超过5),表示问题的总数;M(不超过10^5),表示提交的总数。假定用户ID是5位数的数字,从00001到N,问题ID是从1到K。接下来的一行包含K个正整数,其中每个数字p[i]表示第i个问题的最高分数。然后是M行,每行提供一次提交的信息,格式如下:
user_id problem_id partial_score_obtained
其中partial_score_obtained是以下两种情况之一:如果提交不能通过编译器,则为-1;或者是一个整数,在[0, p[problem_id]]范围内。一行中的所有数字由空格分隔。

输出说明:
对于每个测试案例,需要按照以下格式输出排行榜:
rank user_id total_score s[1] ... s[K]
其中rank是按照total_score计算的排名,如果total_score相同,则获得相同的rank;total_score是用户的总分数;s[i]是用户在第i个问题上获得的部分分数。如果用户从未提交过针对某个问题的解决方案,或者该解决方案没有通过编译器,则相应位置打印"-"。如果用户针对一个问题提交了多个解决方案,则只计算最高分数。排行榜必须按照排名的非递减顺序打印。如果排名相同,用户必须根据完全解决问题的数量按递减顺序排序。如果仍然有平局,则必须按照他们的ID递增顺序打印。那些从未提交过可以通过编译器的解决方案,或者从未提交过任何解决方案的用户,将不会出现在排行榜上。保证至少有一个用户会出现在排行榜上。

代码展示

做不动了…还有一天就要关闭答题咯,等后面有机会再完善吧:( sad


/*利用多关键字排序的思想:先按分数排顺序然后按照解决问题的数量来排序最后按照ID来排序
*/#include <iostream>
#include <string>
#define neverSubmit -1
#define MAX_PROBLEM 6
#define MAX_USERS 10001
#define MAX_SUBMITS 100000
/* 输入信息 */
//struct inputInfo
//{
//	std::string user_id;
//	int problem_id;
//	int partial_score_obtained;
//};
/* 用户个人信息 */
struct userInfo
{	int rank = -1;						/* 排名 */std::string user_id;				/* ID */int nSolve = 0;						/* 完全解决问题的数量 */int score[MAX_PROBLEM] = {-1, -1, -1, -1, -1}; /* 每道题得分情况-存储历史最大得分 -1表示未提交/未通过编译 */int sumScore;					/* 总分 */userInfo* Next = NULL;userInfo* Pre = NULL;
};
/* 表头数组类型 */
struct bucket
{userInfo* First = NULL;userInfo* Last = NULL;
};
/* 获取个位数字 */
int getLow(int score)
{return score % 10;
}
/* 获取十位数字 */
int getMid(int score)
{int temp = score / 10;return temp % 10;
}
/* 获取百位数字 */
int getHigh(int score)
{return score / 100;
}
/* 获取用户信息 */
void getUserInfo(int N, int K, int M, int P[], userInfo user[])
{	std::string user_id;int problem_id;int partial_score_obtained;/* 统计每位用户每道题所得最高分 */for (int i = 0; i < M; i++){std::cin >> user_id >> problem_id >> partial_score_obtained;int id = std::stoi(user_id);user[id].user_id = user_id;/* 将输入的信息存于用户个人信息中 */if (partial_score_obtained >= 0 && partial_score_obtained <= P[problem_id]){/* 如果本次提交大于最大值则更新 */int maxScore = user[id].score[problem_id];if (partial_score_obtained > maxScore)user[id].score[problem_id] = partial_score_obtained;}}/* 计算每位用户所得总分 和 完全解决的问题个数 */for (int i = 1; i <= N; i++){	user[i].sumScore = 0;user[i].nSolve = 0;for (int j = 1; j <= K; j++){	if (user[i].score[j] != -1){user[i].sumScore += user[i].score[j];if (user[i].score[j] == P[j])user[i].nSolve++;}}}
}
/* 复制用户信息 */
void copy(userInfo* SRC, userInfo* ORI, int K)
{SRC->rank = ORI->rank;SRC->sumScore = ORI->sumScore;SRC->user_id = ORI->user_id;for (int i = 0; i < K; i++)SRC->score[i] = ORI->score[i];
}
/* 按照分数进行基数排序 */
void scoreSort(int N, int K, int P[], userInfo user[], bucket highScoreArray[])
{/* 先对分数由高到低排序 基数:10 */bucket lowScoreArray[9];/* 低位排序 */for (int i = 1; i <= N; i++){	/* low取值范围0到9 */int low = getLow(user[i].sumScore);/* 存进对应桶的末尾 */userInfo* newNode = (userInfo*)malloc(sizeof(userInfo));newNode->rank = user[i].rank;newNode->sumScore = user[i].sumScore;newNode->user_id = user[i].user_id;for (int i = 0; i < K; i++)newNode->score[i] = user[i].score[i];/*copy(newNode, &user[i], K);*/newNode->Next = NULL;newNode->Pre = NULL;/* 表头不为空且仅有一个元素 */if (lowScoreArray[low].First && lowScoreArray[low].First == lowScoreArray[low].Last){	lowScoreArray[low].First->Next = newNode;newNode->Pre = lowScoreArray[low].First;lowScoreArray[low].Last = newNode;}/* 表不为空且不止一个元素 */else if(lowScoreArray[low].First && lowScoreArray[low].First != lowScoreArray[low].Last){lowScoreArray[low].Last->Next = newNode;newNode->Pre = lowScoreArray[low].Last;lowScoreArray[low].Last = newNode;}/* 表为空 */else{	lowScoreArray[low].First = newNode;lowScoreArray[low].Last = newNode;newNode->Pre = NULL;}}/* 中位排序 */bucket midScoreArray[9];/* 按顺序从lowScoreArray中取出元素 */userInfo* newNode = lowScoreArray[0].First;int count = 0;int j = 0;while(count != N){while(newNode == NULL && j < 9)newNode = lowScoreArray[++j].First; /* 找到第一个不为空的表头 *//* 从lowScoreArray中取出元素 *//* 表头不为空且仅有一个元素 */if (lowScoreArray[j].First != NULL && lowScoreArray[j].First == lowScoreArray[j].Last )lowScoreArray[j].First = lowScoreArray[j].Last = NULL;/* 若表中不止一个元素 */else if(lowScoreArray[j].First != NULL && lowScoreArray[j].First != lowScoreArray[j].Last)lowScoreArray[j].First = newNode->Next;count++;/* 统计排序的元素个数 *//* 存进对应桶的末尾 */int mid = getMid(newNode->sumScore);	/* 获取第二位置的值 */newNode->Next = NULL;newNode->Pre = NULL;/* 表头不为空且仅有一个元素 */if (midScoreArray[mid].First && midScoreArray[mid].First == midScoreArray[mid].Last){midScoreArray[mid].First->Next = newNode;newNode->Pre = midScoreArray[mid].First;midScoreArray[mid].Last = newNode;}/* 表不为空且不止一个元素 */else if (midScoreArray[mid].First && midScoreArray[mid].First != midScoreArray[mid].Last){midScoreArray[mid].Last->Next = newNode;newNode->Pre = midScoreArray[mid].Last;midScoreArray[mid].Last = newNode;}/* 表为空 */else{midScoreArray[mid].First = newNode;midScoreArray[mid].Last = newNode;newNode->Pre = NULL;}newNode = newNode->Next;	}/* 高位排序 *//* 按顺序从lowScoreArray中取出元素 */newNode = midScoreArray[0].First;count = 0;j = 0;while (count != N){while (newNode == NULL && j < 9)newNode = midScoreArray[++j].First; /* 找到第一个不为空的表头 *//* 从midScoreArray中取出元素 *//* 表头不为空且仅有一个元素 */if (midScoreArray[j].First != NULL && midScoreArray[j].First == midScoreArray[j].Last)midScoreArray[j].First = midScoreArray[j].Last = NULL;/* 若表中不止一个元素 */else if (midScoreArray[j].First != NULL && midScoreArray[j].First != midScoreArray[j].Last)midScoreArray[j].First = newNode->Next;count++;/* 统计排序的元素个数 *//* 存进对应桶的末尾 */int high = getHigh(newNode->sumScore);	/* 获取第二位置的值 */newNode->Next = NULL;newNode->Pre = NULL;/* 表头不为空且仅有一个元素 */if (highScoreArray[high].First && highScoreArray[high].First == highScoreArray[high].Last){highScoreArray[high].First->Next = newNode;newNode->Pre = midScoreArray[high].First;highScoreArray[high].Last = newNode;}/* 表不为空且不止一个元素 */else if (highScoreArray[high].First && highScoreArray[high].First != highScoreArray[high].Last){highScoreArray[high].Last->Next = newNode;newNode->Pre = midScoreArray[high].Last;highScoreArray[high].Last = newNode;}/* 表为空 */else{highScoreArray[high].First = newNode;highScoreArray[high].Last = newNode;}newNode = newNode->Next;}
}
/* 获取排名 */
void getRank(int N, bucket scoreArray[])
{	/* 按顺序从scoreArray中读取元素 */int i = 9;bool flag = false;userInfo* preNode = NULL;userInfo* newNode = NULL;int preIndex;/* 找到最后一个节点 */for (newNode = scoreArray[i].Last; i >= 0;){if (flag == false && newNode == NULL){newNode = scoreArray[--i].Last;}else{	preNode = newNode;preIndex = i;break;}}/* 排序 */flag = false;int preRank; int preScore;int count = 0;newNode = preNode;while(count <= N){	/* 检查当前节点是否为空 */while (newNode == NULL){	if (preIndex > 0){newNode = scoreArray[--preIndex].Last;}else return;}/* 对第一个元素特殊处理 */if (flag == false){newNode->rank = 1;preRank = 1;preScore = newNode->sumScore;flag = true;count++;newNode = newNode->Pre;}else{	/* 总分相同,则排名相同 */if (newNode->sumScore == preScore){newNode->rank = preRank;count++;newNode = newNode->Pre;}/* 总分更低,则排名根据前面的人数更新 */else if (newNode->sumScore < preScore){newNode->rank = ++count;preScore = newNode->sumScore;newNode = newNode->Pre;}}}}
/* 根据解决问题数量再排序一次 */
void nSolveSort(int N, int K, bucket userArray[], bucket problemSolveArray[])
{/* k + 1个桶: 0到K *//* 基数:K + 1 */int i;int count = 0;bool flag = false;	/* flag为false表示此时为第一次排序 */userInfo* newNode = userArray[0].First;userInfo* nextNode;for (i = 0; i < 10; ) //i代表分数桶的数量{		/* 跳到下一个非空桶 */while (flag == true && newNode == NULL){newNode = userArray[++i].First;}/* 找到第一个节点 */while (flag == false && newNode == NULL){newNode = userArray[++i].First;}nextNode = newNode->Next;newNode->Pre = NULL;newNode->Next = NULL;flag = true;/* 根据解决问题数将其放到对应桶 */int numSolve = newNode->nSolve;/* 目标桶为空 */if (problemSolveArray[numSolve].First == NULL){problemSolveArray[numSolve].First = newNode;problemSolveArray[numSolve].Last = newNode;}/* 目标桶仅有一个元素 */else if (problemSolveArray[numSolve].First != NULL && problemSolveArray[numSolve].First == problemSolveArray[numSolve].Last){problemSolveArray[numSolve].First->Next = newNode;newNode->Pre = problemSolveArray[numSolve].First;problemSolveArray[numSolve].Last = newNode;}/* 目标桶不止一个元素 */else{problemSolveArray[numSolve].Last->Next = newNode;newNode->Pre = problemSolveArray[numSolve].Last;problemSolveArray[numSolve].Last = newNode;}newNode = nextNode;}
}void printUserInfo(int K, int P[], userInfo* curUser)
{int i;std::cout << curUser->rank;std::cout << ' ' << curUser->user_id;for (i = 0; i < K; i++){if (curUser->score[i] == -1)std::cout << ' ' << '-';elsestd::cout << ' ' << curUser->score[i];}
}
/* 输出最终信息 */
void output(int N, int K, int P[], bucket problemSolveArray[])
{int count = 0;int i = MAX_PROBLEM;bool flag = false;userInfo* curNode = problemSolveArray[i].First;while (count <= N && i >= 0){	/* 跳到下一个非空桶末尾 */while (flag == true && curNode == NULL){curNode = problemSolveArray[++i].Last;}/* 找到第一个输出的节点 */while (flag == false && curNode == NULL){curNode = problemSolveArray[--i].Last;}flag = true;printUserInfo(K, P, curNode);count++;curNode = curNode->Pre;}
}
/* 根据用户ID再排一次序 */
void idSort(int N, int K, bucket problemSolveArray[])
{/* 用户ID */
}
int main()
{int N, K, M;	/* N:用户总数 K:问题总数 M:提交总数*/int P[MAX_PROBLEM];userInfo user[MAX_USERS];	/* 存储用户信息 */bucket scoreArray[10];bucket problemSolveArray[MAX_PROBLEM + 1];/* 初始化-读取输入 */std::cin >> N >> K >> M;for (int i = 1; i <= K; i++)std::cin >> P[i];/* 统计用户信息 */getUserInfo(N, K, M, P, user);/* 按照分数进行基数排序 */scoreSort(N, K, P, user, scoreArray);/* 获取排名 */getRank(N, scoreArray);/* 根据解决问题数量再排序一次 */nSolveSort(N, K, scoreArray, problemSolveArray);/* 输出 */output(N, K, P, problemSolveArray);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/21100.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++ A (1020) : 幂运算

文章目录 一、题目描述二、参考代码 一、题目描述 二、参考代码 #include<bits/stdc.h> using namespace std; typedef long long ll;void qq(ll a, ll b, ll m) {if (a 0) cout << 0 << endl;;ll out 1;a % m;while (b > 0){if (b & 1)//奇数的最…

[AIGC] Vue2与Vue3的主要区别和示例代码

Vue3是Vue框架的最新版本&#xff0c;它在性能、开发体验和代码体积等方面都有很大的改进。接下来我们将通过比较Vue2和Vue3的主要区别&#xff0c;进一步理解这些改变是如何影响我们的。 文章目录 一、性能提升二、Composition API三、更好的类型支持四、生命周期钩子函数变化…

lux和ffmpeg进行下载各大主流自媒体平台视频

1、lux下载&#xff0c;链接&#xff1a;https://pan.baidu.com/s/1WjGbouL3KFTU6LeqZmACpA?pwdagpp 提取码&#xff1a;agpp 2、ffmpeg下载&#xff0c;跟lux放在同一个目录&#xff1b; 3、为lux、ffmpeg设置环境变量&#xff1b; 4、WINR&#xff0c;打开运行&#xff0…

带你自学大语言模型系列 —— 前言

今天开始&#xff0c;我计划开启一个系列 《带你自学大语言模型》&#xff0c;内容也已经准备了一段时间了。 该系列的落脚点是“自学”和“大语言模型”&#xff0c;二者不分伯仲&#xff0c;这也是本系列和其他技术文章不一样的地方。 至于原因&#xff0c;我不想只做大语言…

【C++】STL中vector常见功能的模拟实现

前言&#xff1a;在上一篇中我们讲到了Vector的一些常见功能的使用方式&#xff0c;今天为了进一步的去学习Vector和能够更深度的去理解Vector的一些底层的原理。 &#x1f496; 博主CSDN主页:卫卫卫的个人主页 &#x1f49e; &#x1f449; 专栏分类:高质量&#xff23;学习 &…

鸿蒙ArkTS声明式开发:跨平台支持列表【禁用控制】 通用属性

禁用控制 组件是否可交互&#xff0c;可交互状态下响应[点击事件]、[触摸事件]、[拖拽事件]、[按键事件]、[焦点事件]和[鼠标事件]。 说明&#xff1a; 开发前请熟悉鸿蒙开发指导文档&#xff1a; gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md点击或者复制转到…

【一刷《剑指Offer》】面试题 30:最小的 k 个数

牛客对应题目链接&#xff1a;最小的K个数_牛客题霸_牛客网 (nowcoder.com) 力扣对应题目链接&#xff1a;LCR 159. 库存管理 III - 力扣&#xff08;LeetCode&#xff09; 核心考点 &#xff1a; topK 问题。 一、《剑指Offer》内容 二、分析题目 1、排序&#xff08;O(Nlo…

接口interfance的基本使用

一.为什么有接口&#xff1f; 接口:就是一种规则。 二.接口的定义和使用 1.接口用关键字interface来定义 public interface 接口名{} 2.接口不能实例化 3.接口和类之间是实现关系,通过implements关键字表示 4.接口的子类(实现类) 注意1&#xff1a; 接口和类的实现关系…

43.自定义线程池(一)

ThreadPool是线程池&#xff0c;里面是一定数量的线程&#xff0c;是消费者。 BlockingQueue阻塞队列&#xff0c;线程池中的线程会从阻塞队列中去拿任务执行。任务多了线程池处理不过来了&#xff0c;就会到Blocking Queue中排队&#xff0c;等待执行。链表结构&#xff0c;特…

Netfilter/iptables

1. Netfilter组件图 https://en.wikipedia.org/wiki/Netfilter 其中&#xff1a; etables作用于数据链路层&#xff0c;arptables针对ARP, iptables/ip6tables针对IP层。 nftables 是新的包过滤组件. nft是相对应的新的用户态组件&#xff0c;用于替换etables,arptables,ipt…

从tensorflow导入EarlyStopping能运行但是一直提示未解析

在pycharm中导入早停机的库时&#xff0c;碰上一个问题 from tensorflow.keras.callbacks import EarlyStopping这一条代码中&#xff0c;EarlyStopping一直有个红色波浪线&#xff0c;代表着找不到这个库&#xff0c;提示未解析啥的。 但是运行是可以运行的&#xff0c;虽然可…

GPT-4o如何重塑AI未来!

如何评价GPT-4o? 简介&#xff1a;最近&#xff0c;GPT-4o横空出世。对GPT-4o这一人工智能技术进行评价&#xff0c;包括版本间的对比分析、GPT-4o的技术能力以及个人感受等。 GPT-4o似乎是一个针对GPT-4模型进行优化的版本&#xff0c;它在性能、准确性、资源效率以及安全和…

Anolis OS 8.9安装Linux 服务器运维管理面板“1Panel”

一、简介 1.Linux 服务器运维管理面板“1Panel” 使用go语言编写 2.很多的项目的应用都是采用 docker 技术来实现&#xff0c;这让 Linux 服务器的运维管理更简单、更安全。 3.1Panel 采纳最新的前端技术&#xff0c;并通过精心设计的UX 交互&#xff0c;为用户提供更好的用户…

Linux系统tab键无法补齐命令-已解决

在CentOS中&#xff0c;按下tab键就可以自动补全&#xff0c;但是在最小化安装时&#xff0c;没有安装自动补全的包&#xff0c;需要安装一个包才能解决 bash-completion 1.检查是否安装tab补齐软件包&#xff08;如果是最小化安装&#xff0c;默认没有&#xff09; rpm -q ba…

关于sprintboot3版本以上中的swagger3.0的使用

文章目录 1.配置pom.xml(添加以下内容&#xff0c;记住点一下右上方maven下载)2.application.properties添加以下配置信息3.新建swagger的config配置信息&#xff0c;文件位置如下4.添加接口注释信息访问swagger文档 1.配置pom.xml(添加以下内容&#xff0c;记住点一下右上方ma…

抽象一个通用的配置冲突解决方案

最近的开发项目中遇到了一个关于配置冲突的解决和产品设计&#xff0c;一直以来都没有处理好。最近抽空整理了一下思路和设计&#xff0c;并做了抽象&#xff0c;后续的类似使用&#xff0c;可以做到直接复用。 思路和代码见&#xff1a;github地址&#xff1a;https://github…

spring:解决findMergedRepeatableAnnotations获取可重复的元注解(meta-annotation)结果不正确问题

spring-core的注解工具提供的方法 AnnotatedElementUtils.findMergedRepeatableAnnotations用于从AnnotatedElement 对象获取可重复的注解。但如果注解本身也是可以定义在其他注解之上的元注解(meta-annotation),且该注解也是可重复注解。这个方法就可能会失效。这就是我最近在…

基于java18多端展示+ idea hbuilder+ mysql家政预约上门服务系统,源码交付,支持二次开发

基于java18多端展示 idea hbuilder mysql家政预约上门服务系统&#xff0c;源码交付&#xff0c;支持二次开发 家政预约上门系统是一种通过互联网或移动应用平台&#xff0c;为用户提供在线预约、下单、支付和评价家政服务的系统。该系统整合了家政服务资源&#xff0c;使用户能…

RabbitMQ三、springboot整合rabbitmq(消息可靠性、高级特性)

一、springboot整合RabbitMQ&#xff08;jdk17&#xff09;&#xff08;创建两个项目&#xff0c;一个生产者项目&#xff0c;一个消费者项目&#xff09; 上面使用原生JAVA操作RabbitMQ较为繁琐&#xff0c;很多的代码都是重复书写的&#xff0c;使用springboot可以简化代码的…

Vue3集成Phaser-飞机大战游戏(设计与源码)

文章目录 引言项目初始化游戏设计和结构游戏程序实现Vue页面嵌入PhaserPreloader 场景加载游戏场景功能实现功能类定义Boom爆炸类Bullet子弹类Enemy敌军类Player玩家类End游戏结束类 总结 更多相关内容可查看 引言 飞机大战&#xff08;也被称为射击游戏或空战游戏&#xff09…