这道题不难,本质就是一个排序,包括局部排序和整体排序,可以想到的基本方法有两种:
- 先局部排序,保存下每个人的局部排名,再进行总体排序计算总排名;
- 先总体排序,并依次输出每个人的总体排名,并同时计算每个人的局部排名;
我采用的是第二种方式。
局部排序的原理和总体排序相同,这里只说一下总体排序的方式。
首先排序肯定是用sort函数,其排序规则定义为:如果分数不同,则分数高的在前,否则id号小的在前,那么sort函数的比较规则就可以写为:
bool cmp(struct human a, struct human b)
{
bool i;
if(a.score!=b.score)
return a.score > b.score;
else
return a.id < b.id;
}
完成了排序需要进行排名,排名需要相同分数则名次相同,我的处理方式是:设定一个排名值rank = 1,除第一名以外,每一名比较和上一名分数,如果相同则直接输出rank,否则rank赋值为该名在数组中的位置+1,再输出rank,局部排名同上,具体代码如下:
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
struct human{
string id;
int score;
int loc;
};
struct human s[30001];
int lrank[101] = {0};
int cScore[101] = {0};
int lcount[101] = {0};
bool cmp(struct human a, struct human b)
{
bool i;
if(a.score!=b.score)
return a.score > b.score;
else
return a.id < b.id;
}
int main()
{
int N;
int count = 0;
cin >> N;
for(int i=0;i<101;i++){cScore[i] = -1;}
for(int i=1;i<=N;i++)
{
int tempN;
cin >> tempN;
for(int j=0;j<tempN;j++)
{
cin >> s[count].id >> s[count].score;
s[count].loc = i;
count++;
}
}
sort(s, s+count, cmp);
int rank = 0;
cout << count << endl;
cout << s[0].id << " " << "1" << " " << s[0].loc << " " << "1" << endl;
rank++;
lrank[s[0].loc] = 1;
cScore[s[0].loc] = s[0].score;
lcount[s[0].loc] = 1;
for(int i=1;i<count;i++)
{
cout << s[i].id << " ";
if(s[i].score!=s[i-1].score)
rank = i+1;
cout << rank << " " << s[i].loc << " ";
lcount[s[i].loc]++;
if(s[i].score!=cScore[s[i].loc])
{
cScore[s[i].loc] = s[i].score;
lrank[s[i].loc] = lcount[s[i].loc];
}
cout << lrank[s[i].loc] << endl;
}
return 0;
}