【題意解析】
有一個打印工作的隊列,每個工作有一個優先級(範圍0~9),數值越大,優先級越高。打印順序要按照優先級由高到低,因此如果隊列頭的工作的優先級不是整個隊列中最大的,那麼就必須回到隊列尾繼續等待。如果隊列頭的工作優先級是最高的,那麼就執行這個打印工作,並將其從隊列中刪除。
給定隊列的長度和你的工作所在的位置(位置標號從隊列頭開始爲0、1、2、3...n-1),要求出完成你的打印工作所需要的時間(包括打印你自己的那個時間)。注意,打印一個工作的時間爲1,從隊列頭移到隊列尾不計時間。
【思路提示】
方法1:直接使用queue來模擬這個過程。
我的實現:
使用priority_queue維護整個隊列的優先級信息,每次可以直接取出最大的優先級。用一個數組存放初始的隊列,數組值爲每個位置的優先級。用數組下標index來記錄隊列頭的位置,將隊列頭移到隊列尾的操作轉換爲下標的移動。當下標所指的工作可以被打印,則將其優先級改爲-1(比最小優先級小),時間加1,從優先隊列中刪除這個最大的優先級(也即刪除priority_queue的隊列頭)。結束條件爲當前工作的優先級最大,且下標index等於你的工作所在的位置m。
【代碼】
#include<iostream>
#include<queue>
#include<string.h>
using namespace std;
int main(){
int n, m, t, hightest, index, time;
int priority[101];
cin >> t;
while (t--){
cin >> n >> m;
for (int i = 0; i < n; ++i)
cin >> priority[i];
int my_pri = priority[m];
priority_queue<int> pq(priority, priority+n);
index = 0;
time = 0;
hightest = pq.top();
while (my_pri < hightest || index != m){
if (hightest <= priority[index]){
time++;
priority[index] = 0-1;
pq.pop();
hightest = pq.top();
}
index++;
if (index >= n)
index = 0;
}
cout << time+1 << endl;
}
return 0;
}
【疑問】
起初,我採用的是用另外一個數組printed[101]來記錄一個工作是否被打印,而不是採用修改已經打印的工作的優先級。爲了能夠再優化一點點,我在循環體末尾增加循環判斷,如果下標所指的工作已經打印,就繼續移動下標而不是進入下一次循環。試了好幾個測例都沒錯,但是就是WA,不知是哪裏出問題了。有知道的歡迎指教。
while (my_pri < hightest || index != m){
if (hightest <= priority[index]){
time++;
printed[index] = 1;
pq.pop();
hightest = pq.top();
}
index++;
while (printed[index] == 1)
index++;
if (index >= n)
index = 0;
}