題目描述
現在有一堆數字共N個數字(N<=10^6),以及一個大小為k的視窗。現在這個從左邊開始向右滑動,每次滑動一個機關,求出每次滑動後視窗中的最大值和最小值。
例如:
The array is [1 3 -1 -3 5 3 6 7], and k = 3.
輸入輸出格式
輸入格式:
輸入一共有兩行,第一行為n,k。
第二行為n個數(<INT_MAX).
輸出格式:
輸出共兩行,第一行為每次視窗滑動的最小值
第二行為每次視窗滑動的最大值
輸入輸出樣例
輸入樣例#1:
8 3
1 3 -1 -3 5 3 6 7
輸出樣例#1:
-1 -3 -3 -3 3 3
3 3 5 5 6 7
說明
50%的資料,n<=10^5
100%的資料,n<=10^6
感覺自己寫代碼越來越精簡了。
stl裡提供了一種叫做deque的雙端隊列。
這種隊列支援在隊首和隊尾插入或者删除。
這樣正好解決了queue不用應用于單調隊列的缺陷。
關于deque的各種用法。
一張圖足以概覽
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIn5GcuYjNxczN0gDO10CM4QDNzcDMxITOwgDM3EDMy0iN5YTMwETMvwFOwcTMwIzLcZTO2EDMxEzLcd2bsJ2Lc12bj5ycn9Gbi52YucTMwIzcldWYtl2Lc9CX6MHc0RHaiojIsJye.png)
對于本題而言。查詢最大最小值其實就是改一下入隊條件的問題,
一個三目運算符解決
#include<iostream>
#include<cstdio>
#include<deque>
using namespace std;
const int MAXN=2000050;
const int maxn=0x7fffffff;
void read(int &n){char c='+';int x=0;bool flag=0;while(c<'0'||c>'9'){c=getchar();if(c=='-')flag=1;}
while(c>='0'&&c<='9'){x=x*10+(c-48);c=getchar();}flag==1?n=-x:n=x;}
int n,k;
int a[MAXN];
struct node
{
int w,p;
node (int a,int b) {w=a;p=b;}
};
deque<node>q;
void find(bool how)
{
while(q.size()) q.pop_front();
for(int i=1;i<=n;i++)
{
while(q.size()!=0&&(how==0?(q.back().w<a[i]):(q.back().w>a[i]))) q.pop_back();
q.push_back(node(a[i],i));
while(q.front().p<=(i-k)) q.pop_front();
if(i>=k) printf("%d ",q.front().w);
}
printf("\n");
}
int main()
{
read(n);read(k);
for(int i=1;i<=n;i++) read(a[i]);
find(1);find(0);
return 0;
}
作者:自為風月馬前卒
個人部落格http://attack204.com//
出處:http://zwfymqz.cnblogs.com/
本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。