洛谷 p1886 滑动窗口

单调队列的一道经典题

单调队列 就是在基础队列的基础上加入单调性, 如果答案有单调性要求可以使用(后出现的弱的答案 无法对当前答案进行影响)

遍历的复杂度是O(n)的

#include<bits/stdc++.h>
using namespace std;

const int maxn = 1e6 + 10;
int min_q[maxn];
int max_q[maxn];
int arr[maxn];
int n, k;
int main()
{
	cin >> n >> k;
	for (int i = 0; i < n; ++i)
	{
		cin >> arr[i];
	}

	int ml = 0, mr = 0;
	min_q[mr] =0;
	if (k == 1)	cout << arr[0] << ' ';
	for (int i =1; i < n; ++i)
	{
		if (arr[i] <= arr[min_q[mr]])	//如果当前值比队列内值优
		{
			while (arr[i] <= arr[min_q[mr]] && ml!=mr)	mr--;
			//将队列尾的次优解踢出
            if (arr[i] <= arr[min_q[mr]])	//是否更新队尾
				min_q[mr]= i;	
			else
				min_q[++mr]=i;		
		}
		else {
			min_q[++mr]=i;
		}
		
		while (min_q[ml] +k<= i)	//将移出的位置踢出
		{
			ml++;
		}
		if (i >= k-1)
		{
			cout << arr[min_q[ml]] << ' ';
		}
		
	}
	cout << endl;
	mr = ml = 0;
	max_q[mr]=0;
	if (k == 1)	cout << arr[0] << ' ';
	for (int i = 1; i < n; ++i)
	{
		if (arr[i] >= arr[max_q[mr]])
		{
			while (arr[i] >= arr[max_q[mr]] && ml != mr)	mr--;
			if (arr[i] >= arr[max_q[mr]])
			{
				max_q[mr]= i;
				
			}
			else
			{
				max_q[++mr] = i;
				
			}

		}
		else {
			max_q[++mr] = i;
		}

		while (max_q[ml]+ k <= i)
		{
			ml++;

		}
		if (i >= k-1)
		{
			cout << arr[max_q[ml]] << " ";
		}
		
	}
	return 0;
}

又学习一遍后 发现用deque代码简单许多 先留坑吧

posted @ 2019-02-17 21:39  新新人類  阅读(114)  评论(0编辑  收藏  举报