日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

25行代码AC——习题5-7 打印队列(Printer Queue,UVa 12100)——解题报告

發布時間:2024/2/28 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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)——解题报告的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。