POJ 2823 Sliding Window

来源:互联网 发布:crm虚拟定位软件 编辑:程序博客网 时间:2024/05/16 08:50

Sliding Window

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

/*ID: csuchenanPROG: POJ 2823LANG: C++*/#include<stdio.h>const int maxn = 1000000 ;#define INF -1u>>1struct Node{int pos ;int val ;}q[maxn + 5] ;int key[maxn + 5] ;void init() ;void work() ;int n ;//number of the sequenceint 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 numberbool first = 0 ;for(i = 1 ; i < k ; i ++){//add data to the min queuewhile(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 queuewhile(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 : csuchenanPROG: POJ 2823LANG: 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  ;}