【POJ 2823】Sliding Window 【滑動視窗/單調佇列入門
阿新 • • 發佈:2018-12-13
題目大意
輸入一個長度為n(n≤≤106106)的數列,給定一個長度為k的視窗,讓這個視窗在數列上移動,求移動到每個位置視窗中包含數的最大值和最小值。即設序列為,設,
求:f(k),f(k+1),…,f(n) g(k),g(k+1),…,g(n).
紫書P241 下面給出程式碼實現:
版本一:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
#define g() getchar()
#define f(i,s,t) for(int i=s;i<=t;i++)
char ch;bool flag;template<class T>inline void r(T &x){
for(flag=0,ch=g();!isdigit(ch);ch=='-'?flag=1:0,ch=g());
for(x=0;isdigit(ch);x=(x<<3)+(x<<1)+ch-'0',ch=g());
flag?x=-x:0;
}
const int maxn = 1000010;
int a[maxn],n,k,que[maxn],ans[maxn];
int main(){
r(n),r(k);f(i,1,n)r(a[i]);
int head=1,tail=1;que[1]=1;ans[1]=a[1];
f(i,2,n){
while(head<=tail&&a[i]<=a[que[tail]])tail--;
que[++tail]=i;
if(head<=tail&&que[head]<(i-k+1))head++;
ans[i] = a[que[head]];//記錄當前最值
}
f(i,k,n)printf("%d ",ans[i]);putchar('\n');
head = 1,tail = 1,que[1] = 1;ans[1]=a[1];
f(i,2,n){
while(head<=tail&&a[i]>=a[que[tail]])tail--;
que[++tail]=i;
if(head<=tail&&que[head]<(i-k+1))head++;
ans[i] = a[que[head]];//記錄當前最值
}
f(i,k,n)printf("%d ",ans[i]);
return 0;
}
(G++要TLE,c++AC,不知道什麼情況…)
版本二:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
#define g() getchar()
#define f(i,s,t) for(int i=s;i<=t;i++)
char ch;bool flag;template<class T>inline void r(T &x){
for(flag=0,ch=g();!isdigit(ch);ch=='-'?flag=1:0,ch=g());
for(x=0;isdigit(ch);x=(x<<3)+(x<<1)+ch-'0',ch=g());
flag?x=-x:0;
}
const int maxn = 1000010;
int a[maxn],n,k,ans[maxn];
deque<int> que;
int main(){
r(n),r(k);f(i,1,n)r(a[i]);
que.push_front(1);ans[1]=a[1];
f(i,2,n){
while(!que.empty()&&a[i]<=a[que.back()])que.pop_back();
que.push_back(i);
if(!que.empty()&&que.front()<(i-k+1))que.pop_front();
ans[i] = a[que.front()];//記錄當前最值
}
f(i,k,n)printf("%d ",ans[i]);putchar('\n');
while(!que.empty())que.pop_back();
que.push_front(1),ans[1]=a[1];
f(i,2,n){
while(!que.empty()&&a[i]>=a[que.back()])que.pop_back();
que.push_back(i);
if(!que.empty()&&que.front()<(i-k+1))que.pop_front();
ans[i] = a[que.front()];//記錄當前最值
}
f(i,k,n)printf("%d ",ans[i]);
return 0;
}