题解:洛谷 P1786 帮贡排序

【题目来源】

洛谷:P1786 帮贡排序 - 洛谷 (luogu.com.cn)

【题目描述】

目前帮派内共最多有一位帮主,两位副帮主,两位护法,四位长老,七位堂主,二十五名精英,帮众若干。

现在 absi2011 要对帮派内几乎所有人的职位全部调整一番。他发现这是个很难的事情。于是要求你帮他调整。

他给你每个人的以下数据:

他的名字(长度不会超过 \(30\)),他的原来职位,他的帮贡,他的等级。

他要给帮贡最多的护法的职位,其次长老,以此类推。

可是,乐斗的显示并不按帮贡排序而按职位和等级排序。

他要你求出最后乐斗显示的列表(在他调整过职位后):职位第一关键字,等级第二关键字。

注意:absi2011 无权调整帮主、副帮主的职位,包括他自己的(这不是废话么..)

他按原来的顺序给你(所以,等级相同的,原来靠前的现在也要靠前,因为经验高低的原因,但此处为了简单点省去经验。)

【输入】

第一行一个正整数 \(n\),表示星月家园内帮友的人数。

下面 \(n\) 行每行两个字符串两个整数,表示每个人的名字、职位、帮贡、等级。

【输出】

一共输出 \(n\) 行,每行包括排序后乐斗显示的名字、职位、等级。

【输入样例】

9
DrangonflyKang BangZhu 100000 66
RenZaiJiangHu FuBangZhu 80000 60
absi2011 FuBangZhu 90000 60
BingQiLingDeYanLei HuFa 89000 58
Lcey HuFa 30000 49
BangYou3 ZhangLao 1000 1
BangYou1 TangZhu 100 40
BangYou2 JingYing 40000 10
BangYou4 BangZhong 400 1

【输出样例】

DrangonflyKang BangZhu 66
RenZaiJiangHu FuBangZhu 60
absi2011 FuBangZhu 60
BingQiLingDeYanLei HuFa 58
BangYou2 HuFa 10
Lcey ZhangLao 49
BangYou1 ZhangLao 40
BangYou3 ZhangLao 1
BangYou4 ZhangLao 1

【算法标签】

《洛谷 P1786 帮贡排序》 #模拟#

【代码详解】

#include <bits/stdc++.h>
using namespace std;

// 定义结构体,表示每个人的信息
struct people 
{
    string name; // 姓名
    string zw;   // 职位
    int bg;      // 贡献值
    int dj;      // 等级
    int sx;      // 序号(输入顺序)
} p[115]; // 最多115个人

// 比较函数1:用于排序贡献值和序号
bool cmp1(people p1, people p2) 
{
    if (p1.bg != p2.bg) return p1.bg > p2.bg; // 贡献值高的排前面
    return p1.sx < p2.sx; // 贡献值相同,序号小的排前面
}

// 将序号转换为职位名称
string its(int n) 
{
    if (n == 0) return "BangZhu";    // 序号0是帮主
    if (n <= 2) return "FuBangZhu";  // 序号1-2是副帮主
    if (n <= 4) return "HuFa";       // 序号3-4是护法
    if (n <= 8) return "ZhangLao";  // 序号5-8是长老
    if (n <= 15) return "TangZhu";  // 序号9-15是堂主
    if (n <= 40) return "JingYing"; // 序号16-40是精英
    return "BangZhong";             // 其余是帮众
}

// 将职位名称转换为序号
int sti(string s) 
{
    if (s == "BangZhu") return 0;    // 帮主
    if (s == "FuBangZhu") return 1;  // 副帮主
    if (s == "HuFa") return 2;       // 护法
    if (s == "ZhangLao") return 3;   // 长老
    if (s == "TangZhu") return 4;    // 堂主
    if (s == "JingYing") return 5;   // 精英
    return 6;                        // 帮众
}

// 比较函数2:用于排序职位、等级和序号
bool cmp2(people p1, people p2)
{
    int tmp1 = sti(p1.zw), tmp2 = sti(p2.zw); // 将职位转换为序号
    if (tmp1 != tmp2) return tmp1 < tmp2; // 职位序号小的排前面
    if (p1.dj != p2.dj) return p1.dj > p2.dj; // 职位相同,等级高的排前面
    return p1.sx < p2.sx; // 等级相同,序号小的排前面
}

int main()
{
    int n; // 人数
    cin >> n; // 输入人数
    for (int i = 0; i < n; i++) 
	{
        cin >> p[i].name >> p[i].zw >> p[i].bg >> p[i].dj; // 输入每个人的信息
        p[i].sx = i; // 记录输入顺序
    }

    // 对第4个人到第n个人按贡献值和序号排序(前3个人是帮主和副帮主,不参与排序)
    sort(p + 3, p + n, cmp1);

    // 根据排序后的序号分配职位
    for (int i = 0; i < n; i++) 
        p[i].zw = its(i); // 将序号转换为职位名称

    // 对第4个人到第n个人按职位、等级和序号排序
    sort(p + 3, p + n, cmp2);

    // 输出每个人的信息
    for (int i = 0; i < n; i++) 
        cout << p[i].name << " " << p[i].zw << " " << p[i].dj << endl;

    return 0;
}

【运行结果】

9
DrangonflyKang BangZhu 100000 66
RenZaiJiangHu FuBangZhu 80000 60
absi2011 FuBangZhu 90000 60
BingQiLingDeYanLei HuFa 89000 58
Lcey HuFa 30000 49
BangYou3 ZhangLao 1000 1
BangYou1 TangZhu 100 40
BangYou2 JingYing 40000 10
BangYou4 BangZhong 400 1
DrangonflyKang BangZhu 66
RenZaiJiangHu FuBangZhu 60
absi2011 FuBangZhu 60
BingQiLingDeYanLei HuFa 58
BangYou2 HuFa 10
Lcey ZhangLao 49
BangYou1 ZhangLao 40
BangYou3 ZhangLao 1
BangYou4 ZhangLao 1
posted @ 2026-02-17 08:26  团爸讲算法  阅读(1)  评论(0)    收藏  举报