这里考察了单调队列。。。第一次接触到队列,无从下手,看了同学的代码,研究了很久才明白是什么意思。。
#include<stdio.h>
#define MAX 1000001
struct queue{
int p; // 数组下标
int x; // 键值
}m[MAX]={0};
int a[MAX]={0};
int main(){
int N,M,i,head,tail; // head: 头指针 tail: 尾指针
scanf("%d %d",&N,&M);
for(i=0;i<N;i++) scanf("%d",&a[i]);
if(M==1){ // 每个数都是最小值和最大值,因为就一个数
for(i=0;i<N-1;i++) printf("%d ",a[i]);
printf("%d\n",a[N-1]);
for(i=0;i<N-1;i++) printf("%d ",a[i]);
printf("%d\n",a[N-1]);
}
else{
m[0].p=0; m[0].x=a[0];
head=0; tail=0;
for(i=1; i<M && i<N; i++){ // 求 M 个数中的最小值
while(tail>=head && m[tail].x>a[i]) tail--; // 如果待插入的值(a[i]) 比 队尾的值(m[tail].x) 小,则删除队尾
m[++tail].x=a[i]; // 把比 m[tail].x大的第一个数插到队尾 .最终只剩下最小值
m[tail].p=i;
}
if(i<N-1) printf("%d ",m[head].x);
else printf("%d\n",m[head].x);
for(i=M;i<N;i++){
while(tail>=head && m[tail].x>a[i]) tail--;
m[++tail].x=a[i];
m[tail].p=i;
while(head<tail && i-m[head].p>=M) head++;
if(i<N-1) printf("%d ",m[head].x);
else printf("%d\n",m[head].x);
}
m[0].p=0; m[0].x=a[0];
head=0; tail=0;
for(i=1;i<M && i<N;i++){
while(tail>=head && m[tail].x<a[i]) tail--;
m[++tail].x=a[i];
m[tail].p=i;
}
if(i<N-1) printf("%d ",m[head].x);
else printf("%d\n",m[head].x);
for(i=M;i<N;i++){
while(tail>=head && m[tail].x<a[i]) tail--;
m[++tail].x=a[i]; m[tail].p=i;
while(head<tail && i-m[head].p>=M) head++;
if(i<N-1) printf("%d ",m[head].x);
else printf("%d\n",m[head].x);
}
}
return 0;
}