紫书刷题进行中,题解系列【GitHub|CSDN】
习题5-7 UVA12100 Printer Queue(32行AC代码)
题目大意
有一个打印队列,每个打印任务优先级为1-9,按如下规则打印:
- 若队首优先级不是最高,则移到队尾;
- 否则打印队首后,令其出队
现计算完全打印第n个位置(0~n-1)需多长时间?
思路分析
定义Job
,其中pos和pty分别表示打印任务的在队列中的位置和打印优先级
struct Job {
int pos, pty; // 位置,优先级
}job;
定义queue<Job> q;
模拟排队过程,定义map<int, int> mp;
记录每个优先级对应的人数,由于,map自动按key升序排列,因此,map最后一个元素的优先级一定是队列最高的。
-
当队首优先级小于队列中最高优先级时,后移到队尾;
-
否则,若队首位置等于目标位置,则结束;若不等,则打印退队,map对应优先级个数-1
AC代码(C++11,queue,map)
#include<bits/stdc++.h>
using namespace std;
struct Job {
int pos, pty; // 位置,优先级
}job;
int T, n, m;
int main() {
scanf("%d", &T);
while (T --) {
scanf("%d %d", &n, &m);
queue<Job> q;
map<int, int> mp; // 每个优先级对应的人数
for (int i = 0; i < n; i ++) {
scanf("%d", &job.pty);
job.pos = i; // 位置,0开始
q.push(job);
mp[job.pty] ++; // 计算该优先级人数
}
int num = 0;
while (!q.empty()) {
if (q.front().pty < mp.rbegin()->first) q.push(q.front()), q.pop(); // 有优先级高者,后移
else if (q.front().pos == m) break; // 目标位置可输出
else { // 非目标位置
if (mp[q.front().pty] == 1) mp.erase(q.front().pty); // 维护mp
else mp[q.front().pty] --;
q.pop(); num ++;
}
}
printf("%d\n", num+1);
}
return 0;
}