使用单调队列
#include <stdio.h>
#define MAXN 1000001
int n,k;
int pre1,pre2,lst1,lst2;//两个队列的首尾指针
int len_max,len_min;//最大值和最小值的下标
int num[MAXN];
int Increase[MAXN],Decrease[MAXN];//单调递增和递减序列,存放序号
int Max[MAXN],Min[MAXN];//最大值和最小值数组
void in_max(int i){//更新递增序列
while (pre1<=lst1&&num[Increase[lst1]]<num[i]) {
--lst1;//尾指针前移
}
Increase[++lst1]=i;//添加新的元素的序号
//如果大于等于k个数,就需要向最大值数组赋值
if (i>=k) {
if (Increase[pre1]<=i-k) {
++pre1;
}
Max[len_max++]=num[Increase[pre1]];
}
}
void in_min(int i){//更新递减序列
while (pre2<=lst2&&num[Decrease[lst2]]>num[i]) {
--lst2;//尾指针前移
}
Decrease[++lst2]=i;
if (i>=k) {
if (Decrease[pre2]<=i-k) {
++pre2;
}
Min[len_min++]=num[Decrease[pre2]];
}
}
int main(){
int i;
while (~scanf("%d%d",&n,&k)) {
//初始化
pre1=pre2=len_max=len_min=0;
lst1=lst2=-1;
//读入数据
for (i=1; i<=n; ++i) {
scanf("%d",&num[i]);
in_max(i);
in_min(i);
}
//输出数据
for (i=0; i<len_min-1; ++i) {//输出最小值
printf("%d ",Min[i]);
}
printf("%d\n",Min[len_min-1]);
for (i=0; i<len_max-1; ++i) {//输出最大值
printf("%d ",Max[i]);
}
printf("%d\n",Max[len_max-1]);
}
return 0;
}
参考:poj2823