PAT真题(C语言)——1025:PAT Ranking(sort()的另一次应用)

在这里插入图片描述
这道题不难,本质就是一个排序,包括局部排序和整体排序,可以想到的基本方法有两种:

  1. 先局部排序,保存下每个人的局部排名,再进行总体排序计算总排名;
  2. 先总体排序,并依次输出每个人的总体排名,并同时计算每个人的局部排名;

我采用的是第二种方式。
局部排序的原理和总体排序相同,这里只说一下总体排序的方式。
首先排序肯定是用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;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值