Sliding Window(单调队列)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_43408238/article/details/89848484

Description

An array of size n ≤ 106 is given to you. There is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k numbers in the window. Each time the sliding window moves rightwards by one position. Following is an example:
The array is [1 3 -1 -3 5 3 6 7], and k is 3.

Window position Minimum value Maximum 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

Your task is to determine the maximum and minimum values in the sliding window at each position.

Input

The input consists of two lines. The first line contains two integers n and k which are the lengths of the array and the sliding window. There are n integers in the second line.

Output

There are two lines in the output. The first line gives the minimum values in the window at each position, from left to right, respectively. The second line gives the maximum values.

Sample Input

8 3
1 3 -1 -3 5 3 6 7

Sample Output

-1 -3 -3 -3 3 3
3 3 5 5 6 7

    

      题意:给你一个数列,在输出所有固定区间k的最小值序列和最大值序列。

      构建一个单调递增队列和单调递减队列,储存的不是原队列的数值而是数值的坐标,便于维护区间k,我一开始一直TLE,换成C++编译器还TLE,后来把cin,cout换成scanf和printf在C++编辑器过了,G++依旧超时。第一次这么深刻的认识到cin的慢速。

 

 

#include<iostream>
#include<iomanip>
//#include<bits/stdc++.h>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<vector>
#include<sstream>
#include<queue>
#include<set>
#define PI  3.14159265358979
#define LL long long
const int MAX=10000100;
#define  eps   0.00000001
using namespace std;
int rise[MAX];int reduce[MAX];int ans[MAX];

int main()
{
//freopen("input.txt","r",stdin);

    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;++i)
    {
        scanf("%d",&ans[i]);
    }
    int head=1,tail=0;
   for(int i=1;i<m;++i)//窗口最小值
    {
        while(head<=tail&&ans[i]<=ans[reduce[tail]]) tail--;
         tail++;
         reduce[tail]=i;
    }
    for(int i=m;i<=n;++i)
    {
        while(head<=tail&&ans[reduce[tail]]>=ans[i]) tail--;
        tail++;
        reduce[tail]=i;
        while(reduce[head]<=i-m) head++;
        printf("%d ",ans[reduce[head]]);
    }
    cout<<endl;
    head=1,tail=0;
    for(int i=1;i<m;++i)//窗口最大值
    {
        while(head<=tail&&ans[i]>=ans[rise[tail]]) tail--;
         tail++;
         rise[tail]=i;
    }
    for(int i=m;i<=n;++i)
    {
        while(head<=tail&&ans[rise[tail]]<=ans[i]) tail--;
        tail++;
        rise[tail]=i;
        while(rise[head]<=i-m) head++;
        printf("%d ",ans[rise[head]]);
    }


}

哇喔,优化cin后G++也可以AC了,惊喜,要知道scanf在G++过不了的。比scanf还快,爽爆了。

#include<iostream>
#include<iomanip>
//#include<bits/stdc++.h>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<vector>
#include<sstream>
#include<queue>
#include<set>
#define PI  3.14159265358979
#define LL long long
const int MAX=10000100;
#define  eps   0.00000001
using namespace std;
int rise[MAX];int reduce[MAX];int ans[MAX];

int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
     //freopen("input.txt","r",stdin);

    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;++i)
    {
        cin>>ans[i];
    }
    int head=1,tail=0;
   for(int i=1;i<m;++i)//窗口最小值
    {
        while(head<=tail&&ans[i]<=ans[reduce[tail]]) tail--;
         tail++;
         reduce[tail]=i;
    }
    for(int i=m;i<=n;++i)
    {
        while(head<=tail&&ans[reduce[tail]]>=ans[i]) tail--;
        tail++;
        reduce[tail]=i;
        while(reduce[head]<=i-m) head++;
        cout<<ans[reduce[head]]<<" ";
    }
    cout<<endl;
    head=1,tail=0;
    for(int i=1;i<m;++i)//窗口最大值
    {
        while(head<=tail&&ans[i]>=ans[rise[tail]]) tail--;
         tail++;
         rise[tail]=i;
    }
    for(int i=m;i<=n;++i)
    {
        while(head<=tail&&ans[rise[tail]]<=ans[i]) tail--;
        tail++;
        rise[tail]=i;
        while(rise[head]<=i-m) head++;
        cout<<ans[rise[head]]<<" ";
    }


}

 

展开阅读全文

没有更多推荐了,返回首页