洛谷P1786

Tomorrowland_D發表於2024-08-15

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;
}