标签:iostream query 最小 cout -- pre 判断 const 优化
用数组queue模拟队列,使用front和tail分别代表收尾指针,初始化front=0, tail=-1
1. 入队:queue[++tail] = x
2. 出队:++front
3. 判空:front > tail 队列为空
4. 获取队头元素: queue[front]
#include <iostream>
using namespace std;
const int N = 100010;
int queue[N], front, tail = -1;
int main()
{
int m;
cin>>m;
while(m--)
{
string op;
int x;
cin>>op;
if(op == "push")
{
cin>>x;
queue[++tail] = x;
}
else if(op == "pop")
{
if(front <= tail) ++front;
}
else if(op == "empty")
{
if(front > tail) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
else if(op == "query")
{
if(front <= tail) cout<<queue[front]<<endl;
}
}
return 0;
}
考虑问题时,先考虑普通队列如何做,然后使用单调队列优化。
适用于两种问题:
1. 滑动窗口min或max
2. 离某个元素最近的值
维护一个单调队列,对头元素为滑动窗口最小的元素
1. 判断当前对头是不是在窗口中
2. 当前元素小于等于队尾元素时(对头元素最小),队尾元素出队
3. 把当前元素下标出入队尾中
4. 输出对头元素min
#include <iostream>
using namespace std;
const int N = 1000010;
int queue[N], arr[N], front = 0, tail = -1;
int main()
{
int n, k;
cin>>n>>k;
for(int i = 0; i < n; i++) cin>>arr[i];
for(int i = 0; i < n; i++)
{
if(front <= tail && queue[front] < i - k + 1) front++;
while(front <= tail && arr[queue[tail]] >= arr[i]) tail--;
queue[++tail] = i;
if(i + 1 >= k) cout<<arr[queue[front]]<<" ";
}
cout<<endl;
front = 0, tail = -1; //记得重新初始化对头和队尾
for(int i = 0; i < n; i++)
{
if(front <= tail && queue[front] < i - k + 1) front++;
while(front <= tail && arr[queue[tail]] <= arr[i]) tail--;
queue[++tail] = i;
if(i + 1 >= k) cout<<arr[queue[front]]<<" ";
}
}
标签:iostream query 最小 cout -- pre 判断 const 优化
原文地址:https://www.cnblogs.com/Trevo/p/12600162.html