25行代码AC——习题5-7 打印队列(Printer Queue,UVa 12100)——解题报告
勵志用盡量少的代碼做高效的表達。
題目(提交)鏈接→UVa-12100
題目描述:
我們需要用打印機打印任務。每個任務都有1~9間的優先級,優先級越高,任務越急。
打印機的運作方式:從打印隊列里取出一個任務j,如果隊列里有比j更急的任務,則直接把j放到打印隊列尾部,否則打印任務j。每次打印都消耗一分鐘的時間,但調整任務位置不消耗時間。
輸入:
第一行:n個測試用例
第二行:m1(任務個數) m2(我們關注的任務所在位置)
第三行:m1個任務的優先級。
…
輸出:
我們關注的任務完成后的時刻。
舉例:
輸入:
1????????????1個測試用例
4 2 ???????????4個任務,我們關注的任務位于4個任務中的第三個(從第0個開始)
1 2 3 4??????????4個任務的優先級
分析:
1、隊頭任務1是否為隊列(1,2,3,4)中優先級最高的? 否,移動到隊列末。此時隊列為:2 3 4 1,時刻為0
2、隊頭任務2是否為隊列(2,3,4,1)中優先級最高的? 否,移動到隊列末。此時隊列為:3 4 1 2,時刻為0
3、隊頭任務3是否為隊列(3,4,1,2)中優先級最高的? 否,移動到隊列末。此時隊列為:4 1 2 3,時刻為0
4、隊頭任務4是否為隊列(4,1,2,3)中優先級最高的? 是,打印任務4。此時隊列變為:1 2 3,時刻從0變為1
5、隊頭任務1是否為隊列(1,2,3)中優先級最高的? 否,移動到隊列末。此時隊列為:2 3 1,時刻為1
6、隊頭任務2是否為隊列(2,3,1)中優先級最高的? 否,移動到隊列末。此時隊列為:3 1 2,時刻為1
7、隊頭任務3是否為隊列(3,1,2)中優先級最高的? 是,打印任務3。時刻從1變為2。
結束判斷,輸出2。
明白了題意,接下來考慮思路:
思路:
最初的思路:
將m1個任務存入隊列,找到隊列中最大的優先級Max。 出隊,若此任務優先級<Max,則入隊(隊尾)。若等于,且不是我們關注的任務:出隊,T++。
若等于,且是我們關注的任務,T++,輸出T。結束循環。
在實施操作中發現了以下幾個難點:
難點1:如何判斷打印的任務是我們關注的任務?
解決辦法:將每個優先級都+10000,若為標記任務的優先級,加20000。優先級間相互判斷前做一下取余。如:10005%10000 = 20005%10000。這種方法叫做自定義標記法。
難點2:最初的想法是在輸入時用Max變量存儲優先級最高的任務, 但如果該任務被打印,Max變動,該怎樣找到當前隊列中優先級最高的任務?
解決辦法:降序優先隊列(priority_queue<int>Max)存儲優先級,每當優先級最高任務被打印,就出隊一次。
最終的思路:
將m1個任務的優先級做標記后存入隊列q(queue<int>q),將不做標記的優先級存入降序優先隊列Max(priority_queue<int>Max)。q出隊,若優先級%10000<Max.top(),則入隊(隊尾), 若優先級%10000=Max.top(),且<20000,q出隊,Max出隊,T++; 若>20000,則輸出T,結束循環。
代碼:
#include<bits/stdc++.h> using namespace std; int main() {int n; cin >> n; while(n--) {int m1, m2; cin >> m1 >> m2; //任務數和關注的任務所在位置int T = 0; //隊列中最大的優先級、時刻 queue<int>q; //主隊列 priority_queue<int>Max; //降序優先隊列,存儲優先級 for(int i = 0; i < m1; i++) { int x; cin>>x; Max.push(x); //壓入優先級(Max 中是原本優先級的數)i == m2 ? x+=20000 : x+= 10000; //將關注任務的優先級做標記 q.push(x); //任務入隊 }while(1) {int x = q.front(); q.pop();if((x%10000) < Max.top()) { q.push(x); } //若不是當前最高優先級,則回隊尾 else if(x >= 20000) { T++; cout << T << endl; break;} //若是,且為關注的任務,則輸出,結束循環。 else { Max.pop(); T++; } //若不是關注的任務,則T++, Max出隊,q出隊,T++ }} return 0; }收獲:
1、才知道隊列是沒有迭代器的。(不要笑話我o(╯□╰)o)
2、自定義標記法做標記
擇苦而安,擇做而樂,虛擬現實終究比不過真實精彩之萬一。
總結
以上是生活随笔為你收集整理的25行代码AC——习题5-7 打印队列(Printer Queue,UVa 12100)——解题报告的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 22行代码AC——习题5-6 对称轴(S
- 下一篇: 大数系列三——斐波那契数列——高效万进制