POJ 2823 Sliding Window/单调队列
来源:互联网 发布:mac nice to meet you 编辑:程序博客网 时间:2024/06/05 06:45
我的心愿是世界和平!
题目描述:第一行给数字n,k,接下来一行给出n个数字,在每k个数字中找到他的最大最小值。输出有两行,分别有n-k+1个数,第一行为最小值,第二行为最大值。注意:n的范围为1e6,暴力会超时。思路:维护一个单调递减的队列,例如 3 2 5 4,3为首,直接入队列(3),2比3小,入队列(3 2),5比2大,2出队列,5比3大,3出队列(5),4比5小,入队列(5 4),这样,队首即为当前数据的最大值,在此题中,需要记录队列中数据的位置,若已经超出k个,则队首出队列。单增队列同上。建议使用双端队列,若用数组模拟双端队列,需注意下标的控制。样例:8 3 1 3 -1 -3 5 3 6 7 // -1 -3 -3 -3 3 3 //3 3 5 5 6 7 3 2 3 2 1 //2 1 //3 2 8 3 -1 2 3 4 5 -9 6 2 //-1 2 3 -9 -9 -9 //3 4 5 5 6 6
双端队列
#include<iostream>#include<queue>#include<cstdio>#define sf scanfconst int M=1e6+10;using namespace std;struct node{ int x; int y;} s[M+50];void Min_Max(int n,int k){ int i; deque<node>q; for(i=1; i<=k; i++) { if(q.empty()||s[i].x>=q.back().x) q.push_back(s[i]); else { while(s[i].x<q.back().x) { q.pop_back(); if(q.empty()) break; } q.push_back(s[i]); } } cout<<q.front().x; for(i=k+1; i<=n; i++) { if(q.empty()||s[i].x>=q.back().x) q.push_back(s[i]); else { while(s[i].x<q.back().x) { q.pop_back(); if(q.empty()) break; } q.push_back(s[i]); } while(q.back().y-q.front().y>=k) q.pop_front(); cout<<" "<<q.front().x; } cout<<endl;}void Max_Min(int n,int k){ int i; deque<node>q; for(i=1; i<=k; i++) { if(q.empty()||s[i].x<=q.back().x) q.push_back(s[i]); else { while(s[i].x>q.back().x) { q.pop_back(); if(q.empty()) break; } q.push_back(s[i]); } } cout<<q.front().x; for(i=k+1; i<=n; i++) { if(q.empty()||s[i].x<=q.back().x) q.push_back(s[i]); else { while(s[i].x>q.back().x) { q.pop_back(); if(q.empty()) break; } q.push_back(s[i]); } while(q.back().y-q.front().y>=k) q.pop_front(); cout<<" "<<q.front().x; }}int main(){ int n,k,i,j; sf("%d%d",&n,&k); for(i=1; i<=n; i++) { sf("%d",&s[i].x); s[i].y=i; } Min_Max(n,k); Max_Min(n,k);}
数组模拟
#include<stdio.h>struct point{ int value; int num;} max[1000001],min[1000001];int s[1000001],ss[1000001];int main(){ int t,i,j,m,n,k,p,maxp=0,minp=0,maxq=0,minq=0; scanf("%d%d",&n,&k); if(k==1) { for(i=0; i<n; i++) { scanf("%d",&m); s[i]=m; ss[i]=m; } t=n; } else { scanf("%d",&m); max[0].value=min[0].value=m; max[0].num=min[0].num=0; p=0; for(i=1; i<k-1; i++) { scanf("%d",&m); if(m<=max[maxq].value) { max[++maxq].value=m; max[maxq].num=i; } else { while(maxq>=maxp&&m>max[maxq].value) maxq--; max[++maxq].value=m; max[maxq].num=i; } if(m>=min[minq].value) { min[++minq].value=m; min[minq].num=i; } else { while(minq>=maxp&&m<min[minq].value) minq--; min[++minq].value=m; min[minq].num=i; } } t=0; for(i=k-1; i<n; i++) { scanf("%d",&m); while(max[maxp].num<p) maxp++; while(min[minp].num<p) minp++; if(m<=max[maxq].value) { max[++maxq].value=m; max[maxq].num=i; } else { while(maxq>=maxp&&m>max[maxq].value) maxq--; max[++maxq].value=m; max[maxq].num=i; } if(m>=min[minq].value) { min[++minq].value=m; min[minq].num=i; } else { while(minq>=minp&&m<min[minq].value) minq--; min[++minq].value=m; min[minq].num=i; } s[t]=min[minp].value; ss[t]=max[maxp].value; t++; p++; } } for(i=0; i<t; i++) printf("%d ",s[i]); printf("\n"); for(i=0; i<t; i++) printf("%d ",ss[i]);}
阅读全文
0 0
- poj 2823 Sliding Window (单调队列)
- POJ 2823 Sliding Window 堆 / 单调队列
- POJ 2823 Sliding Window 单调队列
- poj 2823 Sliding Window 【单调队列】
- poj 2823 Sliding Window(单调队列)
- POJ 2823 Sliding Window(单调队列)
- poj 2823 Sliding Window(简单单调队列)
- POJ 2823 Sliding Window(单调队列)
- POJ 2823 Sliding Window(单调队列)
- poj 2823 Sliding Window(单调队列)
- POJ 2823 Sliding Window(单调队列)
- poj 2823 Sliding Window(单调队列)
- POj 2823 Sliding Window 单调队列
- poj 2823 Sliding Window ( 单调队列 )
- 单调队列--poj-2823-Sliding Window
- POJ 2823 Sliding Window (单调队列)
- POJ:2823 Sliding Window(单调队列)
- POJ 2823 Sliding Window (单调队列)
- 浅谈工程师的调试法宝(三)---SWO引脚的巧妙应用
- cordova 打包android报错
- 几种HTTP url应用
- java 字符串理解
- 分数规划学习、
- POJ 2823 Sliding Window/单调队列
- oracle中关于count(1)、count(*)、count(rowid)、count(某个字段)使用上的区别和性能问题
- Android Tinker的两种接入方式
- 磁盘I/O性能优化--磁盘阵列
- ThinkPHP5 行为和钩子
- MySQL基础学习
- JDBC模板
- hdu 1435 Stable Match (稳定匹配)
- 解决SSH登陆一段时间就断开