6.幫貢排序
題目連結:[P1786 幫貢排序 - 洛谷 | 電腦科學教育新生態 (luogu.com.cn)]()
題目背景
在 absi2011 的幫派裡,死號偏多。現在 absi2011 和幫主等人聯合決定,要清除一些死號,加進一些新號,同時還要鼓勵幫貢多的人,對幫派進行一番休整。
題目描述
目前幫派內共最多有一位幫主,兩位副幫主,兩位護法,四位長老,七位堂主,二十五名精英,幫眾若干。
現在 absi2011 要對幫派內幾乎所有人的職位全部調整一番。他發現這是個很難的事情。於是要求你幫他調整。
他給你每個人的以下資料:
他的名字(長度不會超過 \(30\)),他的原來職位,他的幫貢,他的等級。
他要給幫貢最多的護法的職位,其次長老,以此類推。
可是,樂斗的顯示並不按幫貢排序而按職位和等級排序。
他要你求出最後樂鬥顯示的列表(在他調整過職位後):職位第一關鍵字,等級第二關鍵字。
注意:absi2011 無權調整幫主、副幫主的職位,包括他自己的(這不是廢話麼..)
他按原來的順序給你(所以,等級相同的,原來靠前的現在也要靠前,因為經驗高低的原因,但此處為了簡單點省去經驗。)
輸入格式
第一行一個正整數 \(n\),表示星月家園內幫友的人數。
下面 \(n\) 行每行兩個字串兩個整數,表示每個人的名字、職位、幫貢、等級。
輸出格式
一共輸出 \(n\) 行,每行包括排序後樂鬥顯示的名字、職位、等級。
樣例 #1
樣例輸入 #1
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
樣例輸出 #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
提示
各種職位用漢語拼音代替。
如果職位剩 \(1\) 個,而有 \(2\) 個幫貢相同的人,則選擇原來在前的現在當選此職位。
另:
幫派名號:星月家園
幫主尊號:Dragonfly Kang
幫派ID:2685023
幫派等級:4
幫派人數:101/110
幫派技能:
星月家園資料,歡迎各位豆油加入_
【資料範圍】
對於 \(10\%\) 的資料,保證 \(n=3\)。
對於 \(40\%\) 的資料,保證各個人的幫貢均為 \(0\)。
對於 \(100\%\) 的資料,保證 \(3\leq n\leq 110\),各個名字長度\(\leq30\),\(0\leq\) 各個人的幫貢 \(\leq1000000000\),
\(1\leq\) 各個人等級 \(\leq 150\)。
保證職位必定為 \(\texttt{BangZhu}\),\(\texttt{FuBangZhu}\),\(\texttt{HuFa}\),\(\texttt{ZhangLao}\),\(\texttt{TangZhu}\),\(\texttt{JingYing}\),\(\texttt{BangZhong}\) 之中的一個
保證有一名幫主,保證有兩名副幫主,保證有一名副幫主叫 absi2011
不保證一開始幫派裡所有職位都是滿人的,但排序後分配職務請先分配高階職位。例如原來設一名護法現在設兩名。
保證名字不重複。
【題目來源】
fight.pet.qq.com
absi2011 授權題目
思路:
- 這題我們首先捋清楚思路,我們首先得對幫派中的所有人先分配新的職位,然後根據新的職位,等級和編號進行重新排序後輸出
對所有人分配新的職位:
-
按照題目給出的條件,我們對所有人進行重新分配職位:幫主,副幫主不需要重新分配職位,但是對於下面的人,我們需要先看幫貢是否相同,不同的話就幫貢大的人排前面,否則比較序號,序號小的人排在前面,並且我們只需要從護法開始排序(因為我們陣列是從下標1開始計數,所以說我們只需要從a+4------a+1+n排序即可)。
-
定義結構體和結構體陣列
struct people {
//原先的職位,名字,和新職位
string name, zhiwei,xzw;
//幫貢一定得開long long
long long banggong;
long long dengji;
int num;
}a[125];
int n;
- 按照幫貢來排序,幫貢相同時按序號排序
bool compare(people p1, people p2)
{
if (p1.banggong != p2.banggong) return p1.banggong>p2.banggong;
else return p1.num<p2.num;
}
- 按照幫貢排序,並分配新的職位
//排序,排護法及其後面的所有人
sort(a + 4, a + 1 + n, compare);
for (int i = 1; i <= n; i++) {
if (i == 1) a[i].xzw = "BangZhu";
else if (i >= 2 && i <= 3) a[i].xzw = "FuBangZhu";
else if (i >= 4 && i <= 5) a[i].xzw = "HuFa";
else if (i >= 6 && i <= 9) a[i].xzw = "ZhangLao";
else if (i >= 10 && i <= 16) a[i].xzw = "TangZhu";
else if (i >= 17 && i <= 41) a[i].xzw = "JingYing";
else a[i].xzw = "BangZhong";
}
- 定義新的比較函式,用於排序輸出位置的函式,但是,我們得知道,怎麼去按照職位排序呢?————我們可以定義一個函式,職位高的就返回數字大的,比較它們返回的數字即可
//將職位轉化為數字,方便根據職位來劃分順序,職位越大,數字越大
int change(string s)
{
if (s == "BangZhu") return 6;
else if (s == "FuBangZhu") return 5;
else if (s == "HuFa") return 4;
else if (s == "ZhangLao") return 3;
else if (s == "TangZhu") return 2;
else if (s == "JingYing") return 1;
else return 0;
}
對新的所有人進行順序上的排序
bool compare2(people p1, people p2)
{
if (change(p1.xzw) != change(p2.xzw)) return change(p1.xzw) > change(p2.xzw);
else {
if (p1.dengji != p2.dengji) return p1.dengji > p2.dengji;
else {
return p1.num < p2.num;
}
}
}
最終程式碼
#include<iostream>
#include<algorithm>
using namespace std;
struct people {
string name, zhiwei, xzw;
long long banggong;
long long dengji;
int num;
}a[125];
int n;
bool compare(people p1, people p2)
{
if (p1.banggong == p2.banggong) return p1.num < p2.num;
else return p1.banggong > p2.banggong;
}
//將職位轉化為數字,方便根據職位來劃分順序,職位越大,數字越大
int change(string s)
{
if (s == "BangZhu") return 6;
else if (s == "FuBangZhu") return 5;
else if (s == "HuFa") return 4;
else if (s == "ZhangLao") return 3;
else if (s == "TangZhu") return 2;
else if (s == "JingYing") return 1;
else return 0;
}
bool compare2(people p1, people p2)
{
if (change(p1.xzw) != change(p2.xzw)) return change(p1.xzw) > change(p2.xzw);
else {
if (p1.dengji != p2.dengji) return p1.dengji > p2.dengji;
else {
return p1.num < p2.num;
}
}
}
int main()
{
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i].name >> a[i].zhiwei >> a[i].banggong >> a[i].dengji;
a[i].num = i;
}
//排序,排護法及其後面的所有人
sort(a + 4, a + 1 + n, compare);
for (int i = 1; i <= n; i++) {
if (i == 1) a[i].xzw = "BangZhu";
else if (i >= 2 && i <= 3) a[i].xzw = "FuBangZhu";
else if (i >= 4 && i <= 5) a[i].xzw = "HuFa";
else if (i >= 6 && i <= 9) a[i].xzw = "ZhangLao";
else if (i >= 10 && i <= 16) a[i].xzw = "TangZhu";
else if (i >= 17 && i <= 41) a[i].xzw = "JingYing";
else a[i].xzw = "BangZhong";
}
//再排一次序
sort(a + 1, a + 1 + n, compare2);
for (int i = 1; i <= n; i++) {
cout << a[i].name << " " << a[i].xzw << " " << a[i].dengji << endl;
}
return 0;
}