题目传送门

  理解题意:给定一个数列和窗口范围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;
}

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

相关文章:

  • 2021-10-09
  • 2021-09-17
  • 2021-12-05
  • 2021-08-05
  • 2021-06-24
  • 2021-06-20
  • 2022-02-28
  • 2021-06-04
猜你喜欢
  • 2021-10-18
  • 2021-05-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-11-17
相关资源
相似解决方案