cogs 495. 滑动窗口 单调队列

匿名 (未验证) 提交于 2019-12-02 23:55:01

495. 滑动窗口

★★   输入文件:window.in   输出文件:window.out   简单对比
时间限制:2 s   内存限制:256 MB

【问题描述】

 

给你一个长度为N的数组,一个长为K的滑动的窗体从最左移至最右端,你只能见到窗口的K个数,每次窗体向右移动一位,如下表:

Window position Min value Max value
[1 3 -1] -3 5 3 6 7 -1 3
[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


你的任务是找出窗口在各位置时的max value,min value.

 

【输入格式】

 

第一行n,k,第二行为长度为n的数组

 

【输出格式】

 

第一行每个位置的min value,第二行每个位置的max value

 

【输入输出样例】

window.in
8 3
1 3 -1 -3 5 3 6 7

window.out
-1 -3 -3 -3 3 3
3 3 5 5 6 7

【数据范围】

 

20%:n≤500; 50%:n≤100000;100%:n≤1000000;

 

deque<int> q;

 

 

 

 

 

 

 

#include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<string> #include<cstring> #include<deque> using namespace std; int v[1000005],minn[1000005],maxx[1000005]; int n,k; void Min()//递增  {     deque<int> q;     int i;     q.push_back(1);     minn[1]=v[1];     for(int i=2;i<=n;i++)     {         while(!q.empty()&&v[q.back()]>v[i])             q.pop_back();//把队尾不合法的都弹出去反正也不会是最小的,因为有比他们更小的          q.push_back(i);//放进去          while(!q.empty()&&q.front()<i-k+1)             q.pop_front();//把过时的都弹出去          minn[i]=v[q.front()];//剩下的合法的最小的是队头      }      } void Max()//递减  {     deque<int> q;     int i;     q.push_back(1);     maxx[1]=v[1];     for(int i=2;i<=n;i++)     {         while(!q.empty()&&v[q.back()]<v[i])             q.pop_back();         q.push_back(i);         while(!q.empty()&&q.front()<i-k+1)             q.pop_front();         maxx[i]=v[q.front()];     } } int main() {          scanf("%d%d",&n,&k);          for(int i=1;i<=n;i++)         scanf("%d",&v[i]);     Min();     Max();     for(int i=k;i<n;i++)         printf("%d ",minn[i]);     printf("%d\n",minn[n]);     for(int i=k;i<n;i++)         printf("%d ",maxx[i]);     printf("%d",maxx[n]);     return 0; }

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!