洛谷P1886滑动窗口

Posted H

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷P1886滑动窗口相关的知识,希望对你有一定的参考价值。

  题目传送门

  理解题意:给定一个数列和窗口范围k,求依次向右移动窗口时每次窗口内的最大和最小值。

  没什么思维难度,普及+/提高的标签纯粹是吓唬人的,一边扫过去,用两个数组maxx和minn记录每个窗口内的最大最小值,移动过程中用两个变量L和R记录窗口的左右端点,然后判断滑动窗口时最大最小值是否被移出窗口,进入窗口的值是否大于当前最大值或小于当前最小值,做完后L++,R++,用while循环控制轻松水过这题。当然,如果数据比较极端故意卡时就可能没这么轻松了。(不过我估计也不太可能会有什么题目出这么可怕的数据)

  下面是AC代码:

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#define N 1000010
#define ll long long
using namespace std;
const ll inf=9999999999;
ll n,k,a[N],maxx[N],minn[N];
void ready()
{
  cin>>n>>k;
  for(int i=1;i<=n;i++)
    cin>>a[i];
}
void work()
{
  ll l=1,r=k,cnt=0;
  ll mx=-inf,mn=inf;
  for(int i=l;i<=r;i++){
    mx=max(mx,a[i]);
    mn=min(mn,a[i]);
  }
  maxx[++cnt]=mx;
  minn[cnt]=mn;
  l++;r++;
  while(r<=n){
    if(a[l-1]==mx){
      mx=-inf;
      for(int i=l;i<=r;i++)
    mx=max(mx,a[i]);}
    if(a[l-1]==mn){
      mn=inf;
      for(int i=l;i<=r;i++)
    mn=min(mn,a[i]);}
    if(a[r]>mx)mx=a[r];
    if(a[r]<mn)mn=a[r];
    maxx[++cnt]=mx;
    minn[cnt]=mn;
    l++;r++;
  }
  for(int i=1;i<=cnt;i++)
    cout<<minn[i]<<" ";
  cout<<endl;
  for(int i=1;i<=cnt;i++)
    cout<<maxx[i]<<" ";
}
int main()
{
  //freopen("water.in","r",stdin);
  std::ios::sync_with_stdio(false);
  ready();work();return 0;
}

当然,滑动窗口在其他很多算法中都会用到,所以很有必要掌握好。

以上是关于洛谷P1886滑动窗口的主要内容,如果未能解决你的问题,请参考以下文章

洛谷P1886滑动窗口

洛谷 P1886 滑动窗口

洛谷P1886 滑动窗口 单调队列

洛谷P1886滑动窗口

AC日记——滑动窗口 洛谷 P1886

洛谷 P1886 滑动窗口 (数据与其他网站不同。。)