码迷,mamicode.com
首页 > 其他好文 > 详细

洛谷P1886滑动窗口

时间:2017-11-05 12:21:19      阅读:163      评论:0      收藏:0      [点我收藏+]

标签:mat   using   滑动   代码   include   with   void   循环控制   iostream   

  题目传送门

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

标签:mat   using   滑动   代码   include   with   void   循环控制   iostream   

原文地址:http://www.cnblogs.com/cytus/p/7786955.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!