题目如下:

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)的更多相关文章

  1. 1025 PAT Ranking (25分)

    1025 PAT Ranking (25分) 1. 题目 2. 思路 设置结构体, 先对每一个local排序,再整合后排序 3. 注意点 整体排序时注意如果分数相同的情况下还要按照编号排序 4. 代码 ...

  2. PAT甲级:1025 PAT Ranking (25分)

    PAT甲级:1025 PAT Ranking (25分) 题干 Programming Ability Test (PAT) is organized by the College of Comput ...

  3. 【PAT】1025. PAT Ranking (25)

    题目链接:http://pat.zju.edu.cn/contests/pat-a-practise/1025 题目描述: Programming Ability Test (PAT) is orga ...

  4. 1025 PAT Ranking (25)(25 point(s))

    problem Programming Ability Test (PAT) is organized by the College of Computer Science and Technolog ...

  5. 1025 PAT Ranking (25 分)

    Programming Ability Test (PAT) is organized by the College of Computer Science and Technology of Zhe ...

  6. 1025 PAT Ranking (25分) 思路分析 +满分代码

    题目 Programming Ability Test (PAT) is organized by the College of Computer Science and Technology of ...

  7. PAT 甲级1025 PAT Ranking (25 分)(结构体排序,第一次超时了,一次sort即可小技巧优化)

    题意: 给定一次PAT测试的成绩,要求输出考生的编号,总排名,考场编号以及考场排名. 分析: 题意很简单嘛,一开始上来就,一组组输入,一组组排序并记录组内排名,然后再来个总排序并算总排名,结果发现最后 ...

  8. PAT (Advanced Level) 1025. PAT Ranking (25)

    简单题. #include<iostream> #include<cstring> #include<cmath> #include<algorithm> ...

  9. PAT甲题题解-1025. PAT Ranking (25)-排序

    排序,求整体的排名和局部的排名整体排序,for循环一遍同时存储整体目前的排名和所在局部的排名即可 #include <iostream> #include <cstdio> # ...

随机推荐

  1. 在confluence中出现Handshake failed due to invalid Upgrade header: null

    在confluence中出现Handshake failed due to invalid Upgrade header: null 昨天晚上同事说confluence写完日志保存不了,然后我登陆co ...

  2. Filter,FilterChain,FilterConfig

    实例: package com.zillion.app.filter; import java.io.IOException; import javax.servlet.Filter; import ...

  3. 取list的值

    list.get(0):之类的我就不写了 我就写一个我老忘记的 Iterator it = list.iterator(); while(it.hasNext()){ Student stu = it ...

  4. return、break和continue

    return.break和continue 这三个关键字有一个共同点,那就是读能让后面的语句不执行,不同的地方就是挑的距离不一样. return很强大,如果一个函数中有一个return,并且执行了,那 ...

  5. SAS中的剔除空格函数

    left函数:         刪除字符串左边(开头> 的空格right函数:       刪除字符串右边(结尾> 的空格trim函数:         刪除字符串右边(结尾> 的空 ...

  6. vim 基本命令入门

    简介 vim是Linux 系统下类似于Windows的记事本的编辑器. vim 中经常使用的三种模式 一般模式:浏览文件内容. 插入模式:编辑文件内容. 底行模式:进行保存编辑内容,退出等操作. 基本 ...

  7. Java第1次实验提纲(基本概念与引入PTA+Git)

    0. 控制台下编译.运行 在Notepad++编写Java程序 学会使用控制台,javac.java 学会使用Notepad++ 参考资料: 控制台-cmd应用基础 扫盲教程 使用命令行编译并运行ja ...

  8. Rails多路径调用相同方法原路返回的方法

    有时候可能有多条path到达同一个method,此时,我们希望在该方法完成后自动转到之前进入的path中去,其实实现起来非常简单,只需要实现如下两个方法: def redirect_back_or(d ...

  9. Winform DevExpress控件库(二) 使用SplashScreenManager控件定制程序加载页面

    SplashScreenManager控件:主要作用是显示在进行耗时操作时的等待界面: 位于 工具箱 -> Navigation & Layout(导航栏与布局类控件) 目录下: 在工具 ...

  10. 第一个Angular2的样例

    欢迎跟我一起学习Angular2 本文根据angular2官网手动敲码得来: 本文地址:http://blog.csdn.net/sushengmiyan 本文作者:苏生米沿 - 开发环境搭建 - 配 ...