目录
题目:
7. | 【问题描述】 在选美大奖赛的半决赛现场,有n名选手(2<n<100)参加比赛。比赛结束时,要在现场按照选手的出场顺序宣布最后名次,获得相同分数的选手具有相同的名次,名次连续编号,不用考虑同名次的选手人数。如: 选手数量: 7 选手得分: 5,3,4,7,3,5,6 宣布名次: 3,5,4,1,5,3,2 请编程帮助大奖赛组委会完成半决赛的评分排名工作。 【输入形式】 选手数量:7 选手得分:5 3 4 7 3 5 6 【输出形式】 选手的排名:3 5 4 1 5 3 2 【样例输入】
【样例输出】
【样例说明】 本题的关键在于如何处理同分数的选手排名问题 |
分析:
咋一看这道题很简单,排一下序就行了。但仔细一想,排完序还得判断同分数排名问题。
方法1:使用数组下标表示分数,在出现分数的下标处数组值置为1,没有出现分数的下标处置为0,然后遍历数组将出现分数的下标处值置为相应名次。最后使用下标就可以得出相应分数的名次。需要事先申请一个数组存储分数。这种方法主要问题是分数范围不知道,所以申请数组大小不容易设定。而且实际情况中分数会集中在某个范围内,所以会有大量空间浪费。
方法2:使用STL中map关联式容器,在map中可以将key设置为分数,value设置为名次,因为map容器是自动按照key值升序排序的,所以很好设置名次。再使用一个数组保存原始的分数,这样就可以输出相应分数的名次。而且map中不会有重复的值出现,同分选手排名问题也迎刃而解。
C++STL代码:
#include <iostream>
#include <map>
using namespace std;
int main()
{
int num; //选手个数
int score[100] = {0}; //保存选手分数
int i; //遍历变量
map<int,int> mapCandidate; //map容器存储分数,名次
map<int,int>::iterator iter; //迭代器
int temp; //中间变量
cin >>num; //获取选手人数
for(i=0; i< num; i++)
{
cin >> temp;
score[i] = temp; //保存原始选手分数
mapCandidate[temp]=0; //将map容器key设置为分数,value设置为0.
}
i = mapCandidate.size(); //获取容器大小,因为会有同分选手,map容器会剔除
for(iter = mapCandidate.begin(); iter != mapCandidate.end(); iter++)
{
iter->second = i; //设置对应分数的名次
i--;
}
for(i=0; i < num; i++)
{
iter = mapCandidate.find(score[i]); //使用find()定位数据位置
if(iter != mapCandidate.end() )
cout << iter->second << ' '; //输出相应分数对应名次。
else
cout << "Don't find!";
}
return 0;
}
总结:
熟练使用STL会节省编码时间,而且会让代码看起来更简洁。