1062 Talent and Virtue 25

本文探讨了如何通过C++编程实现对人才数据的综合评估,涉及Talent和Virtue的评分,并提出两种排序思路。第一种采用两阶段排序,第二种直接定义单一比较函数。核心在于利用稳定排序算法确保正确处理并级排名。
摘要由CSDN通过智能技术生成

1062 Talent and Virtue 25

题目链接:A1062 Talent and Virtue 25

问题思路

我尝试了两种思路:

  1. 根据每个人的分数确定其是哪个级别(rank)的人,以总分(德分,学号)排序一次,再以rank排序一次

  2. 根据题目要求规定一种比较规则,一次排序解决问题

思路1将问题复杂化了,是我最开始基于次位优先方法想到的一种思路,列出来的主要原因是提醒自己:

  • 基于MSD和LSD的排序方法要求每次排序使用稳定的排序算法
  • C++sort函数内部是快排实现,不稳定,要用stable_sort

源码

// 思路1
#include <cstdio>
#include <vector>
#include <algorithm>
using std::vector;

class People{
public:
    int talent;
    int virtue;
    int total;
    int id;
    int rank;
    static int lower;
    static int higher;
    People(int id_i, int talent_i, int virtue_i):id(id_i), talent(talent_i), virtue(virtue_i), total(talent_i+virtue_i)
    {
        if(virtue < lower || talent < lower)
            rank = 5;
        else if(virtue < higher && talent > virtue)
            rank = 4;
        else if(talent < higher && virtue < higher)
            rank = 3;
        else if(talent < higher)
            rank = 2;
        else
            rank = 1;
    }
    People(){}
    static bool cmp_total(People a, People b)
    {
        if(a.total > b.total || (a.total == b.total && a.virtue > b.virtue) || (a.total == b.total && a.virtue == b.virtue && a.id < b.id))
            return true;
        else 
            return false;
    }
    static bool cmp_rank(People a, People b)
    {
        if(a.rank < b.rank)
            return true;
        else
            return false;
    }
};
int People::lower = 0;
int People::higher = 0;

int main()
{
    int n;
    vector<People> v;
    scanf("%d %d %d", &n, &People::lower, &People::higher);
    for(int i = 0; i < n; i++)
    {
        int id, talent, virtue;
        scanf("%d %d %d", &id, &virtue, &talent);
        v.push_back(People(id, talent, virtue));
    }
    sort(v.begin(), v.end(), People::cmp_total);
    stable_sort(v.begin(), v.end(), People::cmp_rank);
    int m=0;
    for(auto s = v.rbegin(); s != v.rend(); s++)
    {
        if(s->rank == 5)
            m++;
        else
            break;
    }
    printf("%d\n", n-m);
    for(int i = 0; i < n-m; i++)
    {
        printf("%08d %d %d\n", v[i].id, v[i].virtue, v[i].talent);
    }
    return 0;
}
// 思路2
#include <cstdio>
#include <vector>
#include <algorithm>
using std::vector;

class People{
public:
    int talent;
    int virtue;
    int total;
    int id;
    int rank;
    static int lower;
    static int higher;
    People(int id_i, int talent_i, int virtue_i):id(id_i), talent(talent_i), virtue(virtue_i), total(talent+virtue)
    {
        if(virtue < lower || talent < lower)
            rank = 5;
        else{
            if(virtue < higher && talent > virtue)
                rank = 4;
            else if(talent < higher && virtue < higher)
                rank = 3;
            else if(talent < higher)
                rank = 2;
            else
                rank = 1;
        }
    }
    People(){}
    static bool cmp(People a, People b)
    {
        if(a.rank != b.rank)
            return a.rank < b.rank;
        else if(a.total != b.total)
            return a.total > b.total;
        else if(a.virtue != b.virtue)
            return a.virtue > b.virtue;
        else if(a.id != b.id)
            return a.id < b.id;
    }
};
int People::lower = 0;
int People::higher = 0;

int main()
{
    int n;
    vector<People> v;
    scanf("%d %d %d", &n, &People::lower, &People::higher);
    for(int i = 0; i < n; i++)
    {
        int id, talent, virtue;
        scanf("%d %d %d", &id, &virtue, &talent);
        v.push_back(People(id, talent, virtue));
    }
    sort(v.begin(), v.end(), People::cmp);
    int m=0;
    for(auto s = v.rbegin(); s != v.rend(); s++)
    {
        if(s->rank == 5)
            m++;
        else
            break;
    }
    printf("%d\n", n-m);
    for(int i = 0; i < n-m; i++)
    {
        printf("%08d %d %d\n", v[i].id, v[i].virtue, v[i].talent);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值