您的位置:首页 > 其它

POJ2823 Sliding Window(单调队列)

2016-03-09 20:44 435 查看
题目要输出一个序列各个长度k的连续子序列的最大值最小值。

多次RMQ的算法也是能过的,不过单调队列O(n)。

这题,队列存元素值以及元素下标,队尾出队维护单调性然后入队,队首出队保持新元素下标与队首元素下标差小于k。

以前写的还是3个if-else,重写了下。。不加输出挂会T。。

#include<cstdio>
#include<cstring>
using namespace std;
#define MAXN 1111111
inline void in(int &ret){
char c; int sgn;
while(c=getchar(),c!='-'&&(c<'0'||c>'9')) if(c==EOF) return;
sgn=(c=='-')?-1:1; ret=(c=='-')?0:(c-'0');
while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');
ret*=sgn;
}
void out(int x){
if(x<0){
putchar('-'); out(-x);
return;
}
if(x>9) out(x/10);
putchar(x%10+'0');
}
int que[MAXN],idx[MAXN],front,rear;
int a[MAXN];
int main(){
int n,k;
in(n); in(k);
for(int i=1; i<=n; ++i){
in(a[i]);
}
for(int i=1; i<=n; ++i){
if(front!=rear && idx[front]+k<=i) ++front;
while(front!=rear && que[rear-1]>=a[i]) --rear;
idx[rear]=i; que[rear]=a[i]; ++rear;
if(i>=k){
out(que[front]); putchar(' ');
}
}
putchar('\n');
front=rear=0;
for(int i=1; i<=n; ++i){
if(front!=rear && idx[front]+k<=i) ++front;
while(front!=rear && que[rear-1]<=a[i]) --rear;
idx[rear]=i; que[rear]=a[i]; ++rear;
if(i>=k){
out(que[front]); putchar(' ');
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: