POJ 2823(Sliding Window)

26 篇文章 1 订阅
1 篇文章 0 订阅

今天学习了下单调队列,在网上搜到一篇讲单调队列很不错的博客http://xuyemin520.is-programmer.com/posts/25964 ,单调队列顾名思义就是队列里的元素要单调,怎样维护单调性呢?以上述题目的要求为例。

1.首先看插入元素:为了保证队列的递减性,我们在插入元素v的时候,要将队尾的元素和待插入的val比较,如果队尾的元素不大于val,则删除队尾的元素,然后继续将新的队尾的元素与val比较,直到队尾的元素大于val,这个时候我们才将v插入到队尾。


2.那么队首的元素什么时候删除呢?由于我们只需要保存i的前k-1个元素中的最大值,所以当队首的元素的索引或下标小于 i-k+1的时候,就说明队首的元素对于求f(i)已经没有意义了,因为它已经不在窗里面了。所以当index[队首元素]<i-k+1时,将队首 元素删除。


下面是代码,用G++ TLE,C++才能过

#include <deque>
#include <queue>
#include <cstdio>
#define POB pop_back
#define PUB push_back
#define POF pop_front
using namespace std;
const int N = 1000010;

struct node{
	int idx, val;
}num[N];

int main(){
	int n, i, k;
	while(~scanf("%d%d", &n, &k)){
		queue<int> minQue, maxQue;
		deque<node> down, up;
		for(i = 1;i <= n;i++){
			scanf("%d", &num[i].val);
			num[i].idx = i;
		}
		
		for(i = 1;i <= k - 1;i++){
			//单调递减 
			while(!down.empty()&&down.back().val < num[i].val)
				down.POB();
				down.PUB(num[i]);
			//单调递增
			while(!up.empty()&&up.back().val > num[i].val)
				up.POB();
				up.PUB(num[i]);	 
		}
		for(i = k;i <= n;i++){
			/**维护递减单调队列**/ 
			while(!down.empty()&&down.back().val < num[i].val)
				down.POB();
			down.PUB(num[i]);
			while(!down.empty()&&down.front().idx < i - k + 1)
				down.POF();
			maxQue.push(down.front().val);
			
			/**维护递增单调队列**/  
			while(!up.empty()&&up.back().val > num[i].val)
				up.POB();
			up.PUB(num[i]);
			while(!up.empty()&&up.front().idx < i - k + 1)
				up.POF();
			minQue.push(up.front().val);
		}			
		while(!minQue.empty()){
			printf("%d ", minQue.front());
			minQue.pop();
		}
		printf("\n");
		while(!maxQue.empty()){
			printf("%d ", maxQue.front());
			maxQue.pop();
		}				
		printf("\n");
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值