首页 > 代码库 > Poj2823 单调队列
Poj2823 单调队列
题目大意:
给你一个数字序列,然后给一个从左到右滑动的窗口,窗口的长度是k,一次向右移动一格,每次输出这个窗口中最大的数和最小的数,问最后输出的序列是什么.
思路:
维护两个单调队列,一个维护最大值,一个维护最小值.
因为窗口移动的方向是一直朝一个方向的,所以可以用单调队列维护这个最大值,队列中记录的是最大的那个数的下标.
每向右移动一次,前面出去一个元素,后面进来一个元素,然后维护队列的单调性.
AC代码:
1 //6000ms 1Y 单调队列 需要维护两个单调队列 每一个需要维护它们的开始和结束元素的位置,用一个万能元素当第一个元素,当比较到它时必将 2 //被替换,每一个单调队列中的元素都记录一个作用时间域. 每个元素进队一次出队一次 所以O(n) 3 #include <iostream> 4 #include <cstdio> 5 #include <string.h> 6 #include <stdlib.h> 7 #include <math.h> 8 #include <vector> 9 #include <algorithm> 10 struct node{ 11 int time,v; 12 }; 13 using namespace std; 14 #define maxn 1000005 15 #define INF 0x7fffffff 16 node maxque[maxn],minque[maxn]; 17 int minquelen,maxquelen,minquestart,maxquestart,i,j; 18 int printmin[maxn],printmax[maxn]; 19 void insertmax(int v) 20 { 21 int q; 22 for(q=maxquelen;q>=0;q--) 23 if(maxque[q].v>v) {maxquelen=q+1;maxque[maxquelen].v=v;maxque[maxquelen].time=j;break;} 24 } 25 void insertmin(int v) 26 { 27 int q; 28 for(q=minquelen;q>=0;q--) 29 if(minque[q].v<v) {minquelen=q+1;minque[minquelen].v=v;minque[minquelen].time=j;break;} 30 } 31 int querymax() 32 { 33 if(i<maxque[maxquestart+1].time) 34 return maxque[maxquestart+1].v; 35 else 36 if(i==maxque[maxquestart+1].time) 37 { 38 int temp=maxque[maxquestart+1].v; 39 maxque[++maxquestart]=maxque[0]; 40 return temp; 41 } 42 else 43 { 44 maxque[++maxquestart]=maxque[0]; 45 return querymax(); 46 } 47 } 48 int querymin() 49 { 50 if(i<minque[minquestart+1].time) 51 return minque[minquestart+1].v; 52 else 53 if(i==minque[minquestart+1].time) 54 { 55 int temp=minque[minquestart+1].v; 56 minque[++minquestart]=minque[0]; 57 return temp; 58 } 59 else 60 { 61 minque[++minquestart]=minque[0]; 62 return querymin(); 63 } 64 } 65 int main() 66 { 67 //freopen("in.txt","r",stdin); 68 int n,k; 69 while(~scanf("%d%d",&n,&k)) 70 { 71 int x; 72 if(k>n) k=n; 73 maxque[0].v=INF;minque[0].v=-INF; 74 minquelen=maxquelen=minquestart=maxquestart=0; 75 for(i=1;i<k;i++) 76 { 77 j=i; 78 scanf("%d",&x); 79 insertmax(x); 80 insertmin(x); 81 //cout<<"i="<<i<<" x="<<x<<endl; 82 } 83 /*cout<<"minquestart="<<minquestart<<endl; 84 for(int t=1;t<=minquelen;t++) 85 cout<<"minque["<<t<<"].v="<<minque[t].v<<" minque["<<t<<"].time="<<minque[t].time<<endl; 86 cout<<"maxquestart="<<maxquestart<<endl; 87 for(int t=1;t<=maxquelen;t++) 88 cout<<"maxque["<<t<<"].v="<<maxque[t].v<<" maxque["<<t<<"].time="<<maxque[t].time<<endl; 89 */ 90 //cout<<"adsf"<<endl; 91 for(i=1;i<=n-k+1;i++) //n-k 92 { 93 //cout<<"adsf"<<endl; 94 j=i+k-1; 95 scanf("%d",&x); 96 insertmax(x); 97 insertmin(x); 98 printmax[i]=querymax(); 99 printmin[i]=querymin();100 //cout<<"1"<<endl;101 //cout<<"querymax()="<<printmax[i]<<endl;102 //cout<<"querymin()="<<printmin[i]<<endl;103 }104 for(i=1;i<=n-k+1;i++)105 {106 if(i!=1) printf(" ");107 printf("%d",printmin[i]);108 }109 printf("\n");110 for(i=1;i<=n-k+1;i++)111 {112 if(i!=1) printf(" ");113 printf("%d",printmax[i]);114 }115 printf("\n");116 }117 return 0;118 }
Poj2823 单调队列
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。