POJ 2823 Sliding Window

本文介绍了滑动窗口算法的应用场景及其实现方式,通过两个示例详细展示了如何使用单调队列和优先队列解决区间内最大值与最小值的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Sliding Window

题目意思很简单,求解给定一个区间中的最小与最大,但此题不适合用线段树解,因为区间动态的变化。用单调队列比较适合,也可以用2个堆来维护,一个维护最大,一个维护最小。用单调队列实现的程序如下:

/*
ID: csuchenan
PROG: POJ 2823
LANG: C++
*/

#include<stdio.h>

const int maxn = 1000000 ;
#define INF -1u>>1

struct Node{
	int pos ;
	int val ;
}q[maxn + 5] ;

int key[maxn + 5] ;

void init() ;
void work() ;

int n ;//number of the sequence
int k ;//the 

int main(int argc , char * argv[]){
	
	init() ;
	work() ;
	
	return 0 ;
}

void init(){
	
	scanf("%d %d" , &n , &k) ;
	
	for(int i = 1 ; i <= n ; i ++){
			scanf("%d" , &key[i]) ;
	}
	
	if(n<= k){
		k = n ;
	}
	
	return ; 
}

void work(){
	
	int i ;
	int j ;
	
	int front ;
	int rear  ;
	
	front = 1 ;
	rear  = 0 ;
	
	q[0].val = INF ;
	q[0].pos = 0   ; 
	
	//caculate the min of the k number
	
	bool first = 0 ;
	
	for(i = 1 ; i < k ; i ++){	
		//add data to the min queue
		while(front <= rear && q[rear].val > key[i]){
			rear -- ;
		}
		rear ++ ;
		q[rear].val = key[i] ;
		q[rear].pos = i ;
	}
	
	for(i = k ; i <= n ; i ++){
	
		while(front <= rear && q[rear].val > key[i]){
			rear -- ;
		}
		
		rear ++ ;
		q[rear].val = key[i] ;
		q[rear].pos = i ;
		
		while(front <= rear && q[front].pos <= i - k){
			front ++ ;
		}
		
		if(first)
			printf(" ") ;
		printf("%d" , q[front].val) ;
		first = 1 ;
	}
	
	printf("\n") ;
	
	first = 0 ;
	q[0].val = -INF ;
	q[0].pos = 0   ;
	front = 1 ;
	rear = 0  ;
	
	for(i = 1 ; i < k ; i ++){	
		//add the data to the queue
		while(front <= rear && q[rear].val < key[i]){
			rear -- ;
		}
		rear ++ ;
		q[rear].val = key[i] ;
		q[rear].pos = i ;
	}
	
	for(i = k ; i <= n ; i ++){
	
		while(front <= rear && q[rear].val < key[i]){
			rear -- ;
		}
		
		rear ++ ;
		q[rear].val = key[i] ;
		q[rear].pos = i ;
		
		while(front <= rear && q[front].pos <= i - k){
			front ++ ;
		}
		
		if(first)
			printf(" ") ;
		printf("%d" , q[front].val) ;
		first = 1 ;
	}
	
	return ; 
}

用优先队列来维护的方式如下:

/*
ID : csuchenan
PROG: POJ 2823
LANG: c++
use the priority_queue
*/

#include<stdio.h>
#include<queue>

using namespace std ;

const int maxn = 1000000 ;

struct Node{
	int pos ;
	int val ;
} ;

struct cmpless{
	bool operator()(Node a , Node b){
		return a.val > b.val ;
	}
};

struct cmpgreat{
	bool operator()(Node a , Node b){
		return a.val < b.val ;
	}
};

int key[maxn+5] ;
int res[maxn+5] ;

void init() ; 
void work() ;

int n ;
int k ;

int main(){

	init() ;
	work() ;
	
	return 0 ;
}

void init(){
	
	scanf("%d %d" , &n , &k) ;
	
	for(int i = 1 ; i <= n ; i ++){
		scanf("%d" , &key[i]) ;
	}
	
	return  ;
}	
void work(){

	int i ;
	int j ; 
	
	priority_queue<Node , vector<Node> , cmpless> qmin ;
	priority_queue<Node , vector<Node> , cmpgreat> qmax ;
	
	Node a ;
	
	for(i = 1 ; i < k ; i ++){
		a.val = key[i] ;
		a.pos = i ;
		
		qmin.push(a) ;
		qmax.push(a) ; 
	}
	
	bool first = 0 ;
	int p ;
	p = 0 ;
	
	for(i = k ; i <= n ; i ++){
	
		a.val = key[i] ;
		a.pos = i ;
		
		qmin.push(a) ;
		qmax.push(a) ;
		
		j = i - k ;
		
		while(qmin.top().pos <= j){
			qmin.pop() ;
		}
		if(first){
			printf(" "); 
		}	
		
		printf("%d" , qmin.top().val) ;
		first = 1 ;
		
		while(qmax.top().pos <= j){
			qmax.pop() ;
		}
		
		res[p++] = qmax.top().val ;
	}
	
	printf("\n") ;
	first = 0 ;
	
	for(i = 0 ; i < p ; i ++){
		if(first)
			printf(" ") ;
		printf("%d" , res[i]) ;	
		first = 1 ;
	}
	
	return  ;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值