1025. PAT Ranking (25)
题目如下:
Programming Ability Test (PAT) is organized by the College of Computer Science and Technology of Zhejiang University. Each test is supposed to run simultaneously in several places, and the ranklists will be merged immediately after the test. Now it is your
job to write a program to correctly merge all the ranklists and generate the final rank.
Input Specification:
Each input file contains one test case. For each case, the first line contains a positive number N (<=100), the number of test locations. Then N ranklists follow, each starts with a line containing a positive integer K (<=300), the number of testees, and
then K lines containing the registration number (a 13-digit number) and the total score of each testee. All the numbers in a line are separated by a space.
Output Specification:
For each test case, first print in one line the total number of testees. Then print the final ranklist in the following format:
registration_number final_rank location_number local_rank
The locations are numbered from 1 to N. The output must be sorted in nondecreasing order of the final ranks. The testees with the same score must have the same rank, and the output must be sorted in nondecreasing order of their registration numbers.
Sample Input:
2
5
1234567890001 95
1234567890005 100
1234567890003 95
1234567890002 77
1234567890004 85
4
1234567890013 65
1234567890011 25
1234567890014 100
1234567890012 85
Sample Output:
9
1234567890005 1 1 1
1234567890014 1 2 1
1234567890001 3 1 2
1234567890003 3 1 2
1234567890004 5 1 4
1234567890012 5 2 2
1234567890002 7 1 5
1234567890013 8 2 3
1234567890011 9 2 4
题目要求对数据分别按照地区、全区排名,并且按照名字顺序输出。
我们可以建立一个Person结构体,存储ID、分数、地区号、地区排名。
题目的难点主要在于排名算法和地区、全区分别排名,下面分别讨论。
①排名算法:
首先对所有数据按降序排序,然后相同分数的作为同一个名次,分数不同的时候排名要根据前面相同分数的人数来计算,具体算法如下:
首先利用vector<Person> ps来作为数据容器,先将一个地区的所有数据压入,然后使用sort函数排序,为了满足题目条件,在定义compare函数时应该注意不仅考虑分数高低,还要考虑人名的字典顺序。
sort函数接受compare函数指针,对于元素a、b,系统默认当a < b时应该为true(默认用<比较,升序),为了按分数降序、人名升序,作如下修改:
bool compare(Person a,Person b) // 对sort函数指定比较规则,首先是名字按照字典顺序排序,如果名字相同则按时间顺序
{
if(a.score > b.score){
return true;
}else if(a.score == b.score){
if(a.name < b.name){
return true;
}else{
return false;
}
} return false;
}
排序结束后,分数是按递减顺序分布的,接下来计算排名。定义变量nowScore、rk、numCnt,其中nowScore代表当前计算排名的分数,rk代表当前分数的排名、numCnt代表人数计数器,首先初始化nowScore为第一个人的成绩,也就是最高分,rk初始化为1,numCnt为1,当后面的成绩等于nowScore时,仅把numCnt+1,代表这一分段的人数,当nowScore不等于某个人的分数时,说明到了下一个分数档次,这时候rk等于numCnt,即可得到这个分段的初始排名,同时把nowScore置为这个分数,numCnt不要忘记+1,因为这也是一个人,排名计算具体方法为:
初始化:
int nowScore = all[0].score;
int rk = 1;
int numCnt = 1;
动态计算:注意这里是在这段代码后将rk直接输出,因此没有把rk赋值给其他变量。
Person p = all[i];
if(nowScore != p.score){
rk = numCnt;
nowScore = p.score;
numCnt++;
}else{
numCnt++;
}
②分区排名的算法:
定义两个vector<Person> ps,all;
在一个区的开始,清空ps,然后压入所有数据到ps,排序,接下来从前到后遍历ps,取出Person计算排名,在每个Person中有个单元local_rank用来记录自己的排名,然后把计算之后的Person压入all,一个区结束后再开始下个区,在所有区计算后all中的每个元素都记录着自己的地区排名,这时候只要把all中元素再排序,计算总排名,在输出时即可实现两个排名的输出。
完整源码如下:
#include <iostream>
#include <vector>
#include <algorithm>
#include <string.h>
#include <string> using namespace std; struct Person{ string name;
int score;
int local_rank;
int local_num; Person(string _n, int _s): name(_n), score(_s) {} }; bool compare(Person a,Person b) // 对sort函数指定比较规则,首先是名字按照字典顺序排序,如果名字相同则按时间顺序
{
if(a.score > b.score){
return true;
}else if(a.score == b.score){
if(a.name < b.name){
return true;
}else{
return false;
}
} return false;
} using namespace std; int main()
{
vector<Person> ps;
vector<Person> all;
int N,K;
string name;
int score;
cin >> N;
int i,j,k;
for(i = 0; i < N; i++){
cin >> K;
ps.clear();
for(j = 0; j < K; j++ ){
cin >> name >> score;
ps.push_back(Person(name,score));
}
sort(ps.begin(),ps.end(),compare);
int nowScore = ps[0].score;
int rk = 1;
int numCnt = 1;
for(k = 0; k < ps.size(); k++){
Person p = ps[k];
p.local_num = i + 1;
if(p.score != nowScore){
nowScore = p.score;
rk = numCnt;
numCnt++;
}else{
numCnt++;
}
p.local_rank = rk;
all.push_back(p);
}
} sort(all.begin(),all.end(),compare); int nowScore = all[0].score;
int rk = 1;
int numCnt = 1;
cout << all.size() << endl;
for(i = 0; i < all.size(); i++)
{
Person p = all[i];
if(nowScore != p.score){
rk = numCnt;
nowScore = p.score;
numCnt++;
}else{
numCnt++;
}
cout << p.name << " " << rk << " " << p.local_num << " " << p.local_rank << endl;
} return 0;
}
1025. PAT Ranking (25)的更多相关文章
- 1025 PAT Ranking (25分)
1025 PAT Ranking (25分) 1. 题目 2. 思路 设置结构体, 先对每一个local排序,再整合后排序 3. 注意点 整体排序时注意如果分数相同的情况下还要按照编号排序 4. 代码 ...
- PAT甲级:1025 PAT Ranking (25分)
PAT甲级:1025 PAT Ranking (25分) 题干 Programming Ability Test (PAT) is organized by the College of Comput ...
- 【PAT】1025. PAT Ranking (25)
题目链接:http://pat.zju.edu.cn/contests/pat-a-practise/1025 题目描述: Programming Ability Test (PAT) is orga ...
- 1025 PAT Ranking (25)(25 point(s))
problem Programming Ability Test (PAT) is organized by the College of Computer Science and Technolog ...
- 1025 PAT Ranking (25 分)
Programming Ability Test (PAT) is organized by the College of Computer Science and Technology of Zhe ...
- 1025 PAT Ranking (25分) 思路分析 +满分代码
题目 Programming Ability Test (PAT) is organized by the College of Computer Science and Technology of ...
- PAT 甲级1025 PAT Ranking (25 分)(结构体排序,第一次超时了,一次sort即可小技巧优化)
题意: 给定一次PAT测试的成绩,要求输出考生的编号,总排名,考场编号以及考场排名. 分析: 题意很简单嘛,一开始上来就,一组组输入,一组组排序并记录组内排名,然后再来个总排序并算总排名,结果发现最后 ...
- PAT (Advanced Level) 1025. PAT Ranking (25)
简单题. #include<iostream> #include<cstring> #include<cmath> #include<algorithm> ...
- PAT甲题题解-1025. PAT Ranking (25)-排序
排序,求整体的排名和局部的排名整体排序,for循环一遍同时存储整体目前的排名和所在局部的排名即可 #include <iostream> #include <cstdio> # ...
随机推荐
- Android SDK下载安装及配置教程
2017年12月07日 13:33:32 4942 转载自:http://blog.csdn.net/dr_neo/article/details/49870587 Android开发环境搭建可以分为 ...
- Redis设置Key的过期时间 – EXPIRE命令
EXPIRE key seconds 为给定 key 设置生存时间,当 key 过期时(生存时间为 0 ),它会被自动删除. 操作key对生存时间的影响 生存时间可以通过使用 DEL 命令来删除整个 ...
- bootstrap插件fileinput.js 显示无法上传失败
哪怕图片已经传到服务器上了 依然显示出错 // 处理完成后,必须返回一个json数据,否则会报错误 JSONObject jsonObject = new JSONObject(); jsonObje ...
- java实现微信支付之扫码支付
本文直接从代码调用微信扫码支付讲起.账号配置,参数生成等请参考官方文档:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_1 微信 ...
- 一看你就懂,超详细java中的ClassLoader详解
本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布 ClassLoader翻译过来就是类加载器,普通的Java开发者其实用到的不多,但对于某些框架开发者来说却非常常见.理解ClassL ...
- c++ Struct和Class的区别
C++中的struct对C中的struct进行了扩充,它已经不再只是一个包含不同数据类型的数据结构了,它已经获取了太多的功能.struct能包含成员函数吗? 能!struct能继承吗? 能!!stru ...
- ubuntu 修改计算机名
ubuntu装好系统之后打开终端,命令行前边会有一长串名字,看起来好烦(格式为:用户名@计算机名:~$),所以改计算机名: 需要改两个文件: sudo gedit /etc/hostname sudo ...
- FJUT寒假作业涨姿势题解
题意非常简单易懂,对于涨姿势0,数据非常小,比较容易想到的是直接循环暴力解题完成任务.把数据放入数组arr,循环i,j控制所有区间算和.结果记入vis. 到了涨姿势1,2,3,我们观察数据变化,发现数 ...
- Canvas实现3D效果-可旋转的立方体
摘要:Canvas画布是一个二维平面,如何展示出3D效果?通过将三维空间中的Z轴抽取出来,将图像的点投影到与Z轴垂直的平面上,在通过旋转等变换效果,我们就能实现3D效果. 一.建立坐标系 1)立方体坐 ...
- Dynamics 365 Online 试用账号申请方式
专人整理的申请方式PPT,这里转载给大家,下载地址