1. 程式人生 > >PAT-ADVANCED1056——Mice and Rice

PAT-ADVANCED1056——Mice and Rice

我的PAT-ADVANCED程式碼倉:https://github.com/617076674/PAT-ADVANCED

原題連結:https://pintia.cn/problem-sets/994805342720868352/problems/994805419468242944

題目描述:

題目翻譯:

1056 老鼠和大米

老鼠和大米是程式設計競賽的名稱,每個程式設計師必須編寫一段程式碼來控制給定地圖中老鼠的移動。每隻老鼠的目標是儘可能多地吃大米以成為胖老鼠。

首先,隨機決定NP個程式設計師的比賽順序。每NG個程式設計師在一組中進行比賽。一組中最胖的老鼠獲勝並進入下一回合。本回閤中的所有輸家排名都相同。每組中的獲勝者將進入到下一場比賽中,直到確定最終獲勝者。

為簡單起見,假設一旦程式設計師提交他/她的程式碼,每個老鼠的重量就固定了。 給出所有老鼠的重量和初始比賽順序,你需要輸出程式設計師的排名。

輸入格式:

每個輸入檔案包含一個測試用例。對每個測試用例,第一行包含2個正整數:NP和NG(<= 1000),分別代表程式設計師的數量和一組中的最大老鼠數量。如果在程式設計師列表的最後剩餘的老鼠數量小於NG,則剩下的所有小鼠將被放入最後一組。第二行包含NP個不同的非負數Wi(i = 0,⋯,NP - 1),Wi代表第i個老鼠的重量。第三行給出了初始比賽順序,即0,⋯,NP - 1的排列(假設程式設計師編號從0到NP - 1)。一行中的所有數字由一個空格分隔。

輸出格式:

對每個測試用例,在一行中列印最終排名。 第i個數字是第i個程式設計師的排名,並且所有數字必須用空格分隔,在行的末尾沒有額外的空格。

輸入樣例:

11 3
25 18 0 46 37 3 19 22 57 56 10
6 0 8 7 10 5 9 1 4 2 3

輸出樣例:

5 5 5 2 5 5 5 3 1 3 5

知識點:佇列、優先佇列

思路:按初始比賽順序入隊,並按NG進行分組各自進入一個優先佇列,取每個優先佇列的最高分數進入下一輪比賽佇列

時間複雜度是O(logNG(NP)log(NG)),其中logNG(NP)表示以NG為底NP的對數。空間複雜度是O(NP)。

C++程式碼:

#include<iostream>
#include<queue>
#include<algorithm>

using namespace std;

struct programmer {
	int id;
	int data;
	int rank;
	friend bool operator < (programmer pg1, programmer pg2) {
		return pg1.data < pg2.data;
	}
};

bool cmp(programmer pg1, programmer pg2);

int main() {
	int NP, NG, num;
	scanf("%d %d", &NP, &NG);
	programmer pgs[NP];
	queue<programmer> programmers;
	queue<programmer> tempProgrammers;
	priority_queue<programmer> pqProgrammers;
	for(int i = 0; i < NP; i++) {
		pgs[i].id = i;
		scanf("%d", &pgs[i].data);
	}
	for(int i = 0; i < NP; i++){
		scanf("%d", &num);
		programmers.push(pgs[num]);
	}
	vector<programmer> results;
	int index = 0;
	while(programmers.size() != 1){
		int size = programmers.size();	//佇列programmers中的元素個數一直在變,提前記錄其個數 
		for(int i = 0; i < size; i += NG){
			for(int j = i; j < i + NG && j < size; j++){
				pqProgrammers.push(programmers.front());
				programmers.pop();
			}
			tempProgrammers.push(pqProgrammers.top());
			pqProgrammers.pop();
			while(!pqProgrammers.empty()){
				results.push_back(pqProgrammers.top());
				pqProgrammers.pop();
			}
		}
		while(!programmers.empty()){
			programmers.pop();
		}
		while(!tempProgrammers.empty()){
			programmers.push(tempProgrammers.front());
			tempProgrammers.pop();
		}
		for(int i = index; i < results.size(); i++){
			results[i].rank = programmers.size() + 1;
		}
		index = results.size();
	}
	programmers.front().rank = 1;
	results.push_back(programmers.front());
	sort(results.begin(), results.end(), cmp);
	for(int i = 0; i < results.size(); i++){
		printf("%d", results[i].rank);
		if(i != results.size() - 1){
			printf(" ");
		}
	}
}

bool cmp(programmer pg1, programmer pg2){
	return pg1.id < pg2.id;
}

C++解題報告: