1560: window
时间限制: 1 Sec 内存限制: 128 MB
提交: 7 解决: 4
您该题的状态:已完成
[提交][状态][讨论版]
题目描述
给你一个长度为N的数组,一个长为K的滑动的窗体从最左移至最右端,你只能见到窗口的K个数,每次窗体向右移动一位,如下表:
Window position | Min value | Max value |
[ 1 3 -1 ] -3 5 3 6 7 | -1 | 3 |
1 [ 3 -1 -3 ] 5 3 6 7 | -3 | 3 |
1 3 [ -1 -3 5 ] 3 6 7 | -3 | 5 |
1 3 -1 [ -3 5 3 ] 6 7 | -3 | 5 |
1 3 -1 -3 [ 5 3 6 ] 7 | 3 | 6 |
1 3 -1 -3 5 [ 3 6 7 ] | 3 | 7 |
你的任务是找出窗口在各位置时的max value,min value.
数据范围:
20%: n<=500; 50%: n<=100000;
100%: n<=1000000;
输入
第1行n,k,第2行为长度为n的数组
输出
2行,第1行每个位置的min value,第2行每个位置的max value
样例输入
8 3 1 3 -1 -3 5 3 6 7
样例输出
-1 -3 -3 -3 3 33 3 5 5 6 7
提示
单调队列
应该算是一个单调队列的模板题了吧,单调队列博大精深
#include <stdio.h>
#include <deque>
#define N 1000010
using namespace std;
struct Node {
int id;
int value;
};
int cma,cmi; //下标
int s[N];
int Max[N]; //存储最大值的数组
int Min[N]; //存储最小值的数组
deque<Node> ma;//维护最大值的队列
deque<Node> mi;//维护最小值的队列
//最大值队列进栈
void push_ma( int id , int value ){
Node temp;
temp.id = id;
temp.value = value;
ma.push_back(temp);
}
//最小值队列进栈
void push_mi( int id , int value ){
Node temp;
temp.id = id;
temp.value = value;
mi.push_back(temp);
}
int main(){
int n,k;
while( ~scanf( "%d%d",&n,&k ) ){
cma = cmi = 0;
for( int i=0 ; i<n ; i++ )
scanf( "%d",&s[i] );
push_ma( 0,s[0] );
push_mi( 0,s[0] );
for( int i=1 ; i<k ; i++ ){
//更新前k个值中的最大值
while( !ma.empty() && s[i]>=ma.back().value )
ma.pop_back();
push_ma( i,s[i] );
//更新前k个值中的最小值
while( !mi.empty() && s[i]<=mi.back().value )
mi.pop_back();
push_mi( i,s[i] );
}
//取得第一个元素
Max[cma++] = ma.front().value;
Min[cmi++] = mi.front().value;
for( int i=k ; i<n ; i++ ){
//每次更新最大值队列
while( !ma.empty() && s[i]>=ma.back().value )
ma.pop_back();
push_ma( i,s[i] );
//更新最小值队列
while( !mi.empty() && s[i]<=mi.back().value )
mi.pop_back();
push_mi( i,s[i] );
//将已不再范围内的最大值队列元素出队 ,数组取得当前位的最大值
while( ma.front().id<=i-k )
ma.pop_front();
Max[cma++] = ma.front().value;
//将已不再范围内的最小值队列元素出队
while( mi.front().id<=i-k )
mi.pop_front();
Min[cmi++] = mi.front().value;
}
//输出
for( int i=0 ; i<cma-1 ; i++ )
printf( "%d ",Min[i] );
printf( "%d\n",Min[cma-1] );
for( int i=0 ; i<cmi-1 ; i++ )
printf( "%d ",Max[i] );
printf( "%d\n",Max[cmi-1] );
}
}
有什么想法欢迎交流~~~