【题目来源】
https://www.lanqiao.cn/problems/3749/learning/
【题目描述】
小蓝是一位在校学生,他经营着一家小型打印店,店里只有一台老式的复印机。然而,学校的同学们每天都有许多文件需要打印,这使得小蓝的复印机总是忙个不停。每一个打印任务都有其重要性,小蓝用一个 1 到 9 的数字来表示,数字越大表示这个任务越重要。复印机的运行规则如下:从待打印任务队列中取出一个任务,如果队列中还有比这个任务更重要的任务,那么就把这个任务放回队列的尾部,等待下一次打印;否则就开始打印这个任务。需要注意的是,一旦开始打印任务,就不会再把它放回打印队列。我们假设每个打印任务都需要 1 分钟才能完成。现在,假设你是小蓝的好朋友小桥,你刚刚交给小蓝一个打印任务,你想知道你的打印任务何时能完成。你的任务目前在打印队列中的位置是已知的(队列的最前面的位置为 0),你能帮助小桥计算出他的打印任务完成的时间吗?
【输入格式】
第一行包含两个整数 N 和 X,表示打印队列中任务的数量和小桥的打印任务在队列中的位置。
第二行包含 N 个整数,分别表示队列中每个任务的重要性。
数据范围保证:1≤N≤100。
【输出格式】
输出一行,表示小桥的打印任务完成的时间。
【输入样例】
3 1
1 7 1
【输出样例】
1
【算法分析】
● 优先队列:https://blog.csdn.net/hnjzsyjyj/article/details/108929993
优先队列 priority_queue,本质上是用堆实现的。
(1)升序队列,小根堆:priority_queue <int,vector<int>,greater<int> > p;
(2)降序队列,大根堆:priority_queue <int,vector<int>,less<int> >q;
(3)对于基础数据类型,默认是大顶堆:priority_queue<int> r; // 等同于 priority_queue<int, vector<int>, less<int> > r;
依据本题题意“数字越大任务越重要”、“重要的任务先打印”,可知本题要使用优先队列中的大根堆。
priority_queue<int,vector<int>,less<int>> pq;
● pair 简介:https://blog.csdn.net/hnjzsyjyj/article/details/108929993
pair 将两个数据(经常为不同数据类型)组合成一组数据。
pair 的实现是一个结构体,主要的两个成员变量是 first、second。
pair 的比较规则:先比较第一个元素,第一个相等比较第二个。
● 本题算法的执行过程
输入样例: 3 0 1 7 2 | 输出样例: 3 | |
ans | q | pq |
0 | (0,1) (1,7) (2,2) | 7 2 1 |
0 | (1,7) (2,2) (0,1) | 7 2 1 |
1 | (2,2) (0,1) | 2 1 |
2 | (0,1) | 1 |
3 | (0,1) | 1 |
● 在程序设计中,队列(含优先队列、双端队列等)通常不支持使用下标访问,因为队列的设计目的是为了高效地处理元素的入队和出队操作,而不是随机访问。如果需要随机访问元素,通常使用数组等数据结构更为合适。
【算法代码】
#include <bits/stdc++.h>
using namespace std;
queue<pair<int,int>> q;
priority_queue<int,vector<int>,less<int>> pq;
int main() {
int n,pos;
cin>>n>>pos;
for(int i=0;i<n;i++){
int x;
cin>>x;
q.push({i,x});
pq.push(x);
}
int ans=0;
while(1){
if(q.front().second != pq.top()){
q.push(q.front());
q.pop();
} else {
ans++;
if(q.front().first == pos) {
cout<<ans<<endl;
break;
}
q.pop();
pq.pop();
}
}
return 0;
}
/*
in:
3 0
1 7 2
out:
3
*/
【参考文献】
https://www.lanqiao.cn/problems/3749/learning/
https://blog.csdn.net/hnjzsyjyj/article/details/108929993