题目链接:http://poj.org/problem?id=2823
题目大意:有n个数字,从左至右输出每个长度为m的数列段的最小值和最大值
题目思路:经典滑窗最值问题。首先先对前m-1个数字建立单调队列,以最大为例,单调队列就是从队尾插入,遇到小于等于该数字的就把他删掉,直到删光或者遇到比他大的数字。对于m到n个数字,每插入一个数字维护完后的队首就是想要的答案。这里的维护分为两步。第一步是观察队首对应数字所在的位置。如果队首不在考察范围内,那就把它踢出去,第二步的插入跟之前的一模一样,复制粘贴即可。然后每次都记录答案就行。
以下是手动模拟版代码:
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<cstdio>
using namespace std;
#define inf 0x3f3f3f3f
#define MAXN 1000005
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
struct node{
int pos,val;
}maxque[MAXN],minque[MAXN];
int minans[MAXN],maxans[MAXN];
int main(){
int n,k,x;
while(~scanf("%d%d",&n,&k)){
int maxhead=1,maxtail=1;
int minhead=1,mintail=1;
rep(i,1,k-1){
scanf("%d",&x);
while(maxhead<maxtail&&maxque[maxtail-1].val<=x)maxtail--;
while(minhead<mintail&&minque[mintail-1].val>=x)mintail--;
maxque[maxtail].pos=i;maxque[maxtail++].val=x;
minque[mintail].pos=i;minque[mintail++].val=x;
}
rep(i,k,n){
while(maxhead<maxtail&&maxque[maxhead].pos<i-k+1)maxhead++;
while(minhead<mintail&&minque[minhead].pos<i-k+1)minhead++;
scanf("%d",&x);
while(maxhead<maxtail&&maxque[maxtail-1].val<=x)maxtail--;
while(minhead<mintail&&minque[mintail-1].val>=x)mintail--;
maxque[maxtail].pos=i;maxque[maxtail++].val=x;
minque[mintail].pos=i;minque[mintail++].val=x;
maxans[i]=maxque[maxhead].val;
minans[i]=minque[minhead].val;
}
rep(i,k,n){
printf("%d%c",minans[i],i==n?'\n':' ');
}
rep(i,k,n){
printf("%d%c",maxans[i],i==n?'\n':' ');
}
}
return 0;
}
deque很好用 stl真香 但是用deque需要9秒,但是手动模拟只用5秒...
以下是deque代码:
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<list>
using namespace std;
#define inf 0x3f3f3f3f
#define MAXN 1000005
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
struct node{
int pos,val;
}a;
deque<node>maxq,minq;
int maxans[MAXN],minans[MAXN];
int main(){
int n,k,x;
while(~scanf("%d%d",&n,&k)){
while(!maxq.empty())maxq.pop_back();
while(!minq.empty())minq.pop_back();
rep(i,1,k-1){
scanf("%d",&x);
while(!maxq.empty()&&maxq.back().val<=x)maxq.pop_back();
while(!minq.empty()&&minq.back().val>=x)minq.pop_back();
a.pos=i,a.val=x;
maxq.push_back(a);
minq.push_back(a);
}
rep(i,k,n){
while(!maxq.empty()&&maxq.front().pos<i-k+1)maxq.pop_front();
while(!minq.empty()&&minq.front().pos<i-k+1)minq.pop_front();
scanf("%d",&x);
while(!maxq.empty()&&maxq.back().val<=x)maxq.pop_back();
while(!minq.empty()&&minq.back().val>=x)minq.pop_back();
a.pos=i,a.val=x;
maxq.push_back(a);
minq.push_back(a);
maxans[i]=maxq.front().val;
minans[i]=minq.front().val;
}
rep(i,k,n){
printf("%d%c",minans[i],i==n?'\n':' ');
}
rep(i,k,n){
printf("%d%c",maxans[i],i==n?'\n':' ');
}
}
return 0;
}