滑动窗口题解Poj 2823 单调队列数组实现

http://poj.org/problem?id=2823

模拟

n=8 k=3
1 3 -1 -3 5 3 6 7 
先求最大值,用单调递减队列,输出队头

head=1,这样q[head]就直接是队首元素下标了
h=1    t=0
i=1    1    空队列,1入队    h=1 t=1  
i=2    3    1<3出队            h=1 t=1
i=3    3 -1    3>-1,-1入队    i>=k,输出队头3
i=4    3 -1 -3    -1>-3,-3入队    i>=k,输出队头3
i=5    5    3的下标为2,i-2>=k,3出队    -3<5,-3出队,-1<5,-1出队    i>=k,输出队头5
i=6    5 3    5>3,3入队,输出队头5
i=7    6    3<6,3出队,5<6,5出队    输出队头6
i=8    7    6<7,6出队    输出队头7
3 3 5 5 6 7    

#include<cstdio>
#include<iostream>
using namespace std;
const int N=1e6+1;
int n,k,a[N],q[N];//a存放数据,q存放下标
int head=1,tail;//head<tail时队列非空 	令head=1是因为这样的话q[head]就是队首元素下标了,否则head需要加一 
int main(){
	scanf("%d%d",&n,&k);
	//求最小值,用递增序列,输出队尾 
	head=1,tail=0;
	for(int i=1;i<=n;i++)
	{
		scanf("%d",a+i);
		//入队前先维护队列,head<=tail则队列非空 
		//改变队头的情况: i-q[head]>=k,队头出队,即head++
		while(head<=tail && i-q[head]>=k)	head++;
		//改变队尾的情况:  待入队元素小于队尾a[i]<a[q[tail]] ,则tail--
		while(head<=tail && a[i]<a[q[tail]])	tail--; 
		//入队
		q[++tail]=i;
		//如果i>=k,输出队头,其下标为q[head] 
		if(i>=k)
		{
			printf("%d ",a[q[head]]); 
		}	
	}	
	printf("\n");
	//求最大值,用递减序列,输出队头 
	head=1,tail=0;
	for(int i=1;i<=n;i++)
	{
		//入队前先维护队列,head<=tail则队列非空 
		//改变队头的情况: i-q[head]>=k,队头出队,即head++
		while(head<=tail && i-q[head]>=k)	head++;
		//改变队尾的情况:  待入队元素大于队尾a[i]>a[q[tail]] ,则tail--
		while(head<=tail && a[i]>a[q[tail]])	tail--; 
		//入队
		q[++tail]=i;
		//如果i>=k,输出队头,其下标为q[head] 
		if(i>=k)
		{
			printf("%d ",a[q[head]]); 
		}	
	} 
	return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值