题目传送门

题意:给你一个长度为n的数列,然后用一个长度为k的窗口去框(k<n)每次保存k这个窗口中的最大值和最小值,输出。

思路:这道题最朴素的on2的做法铁定超时,然后我想过一个nlogn的方法,网上有人说可以过,但我t了,当时队里的学长讲了单调队列这个知识点,现在才补了题。思路其实很简单,代码有注释,草稿纸准备好,直接看吧。

#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<sstream>
#include<cstring>
#include<bitset>
#include<cstdio>
#include<string>
#include<deque>
#include<stack>
#include<cmath>
#include<queue>
#include<set>
#include<map>
#define INF 0x3f3f3f3f
#define CLR(x,y) memset(x,y,sizeof(x))
#define LC(x) (x<<1)
#define RC(x) ((x<<1)+1)
#define MID(x,y) ((x+y)>>1)
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const double PI=acos(-1.0);
const int maxn=1e6+10;
int fact[10]= {1,1,2,6,24,120,720,5040,40320,362880};
struct dian {
int val,pos;//值 位置
};
dian maxque[maxn],minque[maxn];//结构体模拟队列
int maxhead,maxtail,minhead,mintail;//递减队列(max) 头 尾 递增(max) 头 尾
int maxans[maxn],minans[maxn];//输出的答案
int main() {
int n,k;
cin>>n>>k;
int x;
for(int i=0; i<k; i++) {
scanf("%d",&x);
while(maxhead<maxtail&&maxque[maxtail-1].val<=x)maxtail--;//如果前一个小于当前输入的 那当窗口从前向后移动时 肯定是选择当前这个大的值,所以前面小的就不需要保存了
maxque[maxtail].val=x;
maxque[maxtail++].pos=i;//记录位置 为之后窗口的移动做准备
while(minhead<mintail&&minque[mintail-1].val>=x)mintail--;//同理
minque[mintail].val=x;
minque[mintail++].pos=i;
}
int cur=1;
for(int i=k; i<n; i++) {
minans[cur]=minque[minhead].val;//记录答案 队列头保存的是最小的值
maxans[cur++]=maxque[maxhead].val;
scanf("%d",&x);
while(maxhead < maxtail && maxque[maxhead].pos <= i-k)maxhead++;//窗口移动后 位置不符合要求的pop出去
while(maxhead < maxtail && maxque[maxtail-1].val <= x)maxtail--;//对值进行之前做过的判断
maxque[maxtail].val=x;
maxque[maxtail++].pos=i;
while(minhead < mintail && minque[minhead].pos <= i-k)minhead++;//同理
while(minhead < mintail && minque[mintail-1].val >= x)mintail--;
minque[mintail].val=x;
minque[mintail++].pos=i; }
minans[cur]=minque[minhead].val;
maxans[cur++]=maxque[maxhead].val;
for (int i = 1; i < cur; ++i) {
if (i > 1) putchar(' ');
printf("%d", minans[i]);
}
printf("\n");
for (int i = 1; i < cur; ++i) {
if (i > 1) putchar(' ');
printf("%d", maxans[i]);
}
printf("\n");
}
Sliding Window
Time Limit: 12000MS   Memory Limit: 65536K
Total Submissions: 67150   Accepted: 19065
Case Time Limit: 5000MS

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

poj2823滑动窗口(单调队列)的更多相关文章

  1. [POJ2823]Sliding Window 滑动窗口(单调队列)

    题意 刚学单调队列的时候做过 现在重新做一次 一个很经典的题目 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口.现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗 ...

  2. POJ 2823 滑动窗口 单调队列

    https://vjudge.net/problem/POJ-2823 中文:https://loj.ac/problem/10175 题目 给一个长度为 $N$ 的数组,一个长为 $K$ 的滑动窗体 ...

  3. luoguP1886 滑动窗口 [单调队列]

    题目描述 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口.现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值. 例如: The array i ...

  4. [洛谷P1886]滑动窗口 (单调队列)(线段树)

    ---恢复内容开始--- 这是很好的一道题 题目描述: 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口. 现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的 ...

  5. [Luogu P1886]滑动窗口--单调队列入门

    题目描述 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口.现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值. 例如: The array i ...

  6. AcWing 154. 滑动窗口 单调队列

    地址 https://www.acwing.com/problem/content/description/156/ 输入格式 输入包含两行. 第一行包含两个整数n和k,分别代表数组长度和滑动窗口的长 ...

  7. 洛谷 P1886 滑动窗口(单调队列)

    题目链接 https://www.luogu.org/problemnew/show/P1886 题目描述 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口.现在这个从左边开始 ...

  8. cogs 495. 滑动窗口 单调队列

    495. 滑动窗口 ★★   输入文件:window.in   输出文件:window.out   简单对比时间限制:2 s   内存限制:256 MB [问题描述] 给你一个长度为N的数组,一个长为 ...

  9. POJ 2823 滑动窗口 单调队列模板

    我们从最简单的问题开始: 给定一个长度为N的整数数列a(i),i=0,1,...,N-1和窗长度k. 要求: f(i) = max{a(i-k+1),a(i-k+2),..., a(i)},i = 0 ...

  10. Acwing 154 滑动窗口(单调队列)经典模板

    给定一个大小为n≤106n≤106的数组. 有一个大小为k的滑动窗口,它从数组的最左边移动到最右边. 您只能在窗口中看到k个数字. 每次滑动窗口向右移动一个位置. 以下是一个例子: 该数组为[1 3 ...

随机推荐

  1. setAttribute这个方法

    setAttribute这个方法,在JSP内置对象session和request都有这个方法,这个方法作用就是保存数据,然后还可以用getAttribute方法来取出.比如现在又个User对象,Use ...

  2. SQL基础E-R图基础

    ER图分为实体.属性.关系三个核心部分.实体是长方形体现,而属性则是椭圆形,关系为菱形. ER图的实体(entity)即数据模型中的数据对象,例如人.学生.音乐都可以作为一个数据对象,用长方体来表示, ...

  3. jquery datatable 多行(单行)选择(select),行获取/行删除

    jquery datatable 多行(单行)选择(select),行获取/行删除 代码展示 // 示例数据源 var dataSet = [ ['Tasman','Internet Explorer ...

  4. 第2章 netty介绍与相关基础知识

    NIO有一个零拷贝的特性.Java的内存有分为堆和栈,以及还有字符串常量池等等.如果有一些数据需要从IO里面读取并且放到堆里面,中间其实会经过一些缓冲区.我们要去读,它会分成两个步骤,第一块它会把我们 ...

  5. OpenCV Mat数据类型指针ptr的使用

    OpenCV Mat数据类型指针ptr的使用 cv::Mat image = cv::Mat(400, 600, CV_8UC1); //宽400,长600 uchar * data00 = imag ...

  6. 华为JAVA机试流程

    1.JAVA机试流程:①打开IE浏览器,输入机试系统IP地址(以当天告知的地址为准):②输入姓名.手机,选择“C/C++”或“JAVA”,登录:③登录后显示题目,阅读题目并点击页面最下方的“下载框架文 ...

  7. p3295 [SCOI2016]萌萌哒

    传送门 分析 我们可以将一个点拆成logN个点,分别代表从点i开始,长度为2^k的子串 那么当我们处理两个区间相等的关系时,对区间做二进制拆分,拆成log个区间,分别并起来即可 当然我们这样做修改是省 ...

  8. loj10099 矿场搭建

    传送门 分析 我们发现可以将这张图转换为一个联通块来处理.我们求出所有的割点.在求完之后我们我们对于每一个点双连通分量如果它没有割点相连则需要布置两个出口,因为可能有一个出口正好被割掉.而如果有一个割 ...

  9. struts学习记录

    see also:http://blog.csdn.net/chenggil10/article/details/5965806#_Toc250472631 0.struts2每一个请求,都new一个 ...

  10. [译]Javascript的弱点

    本文翻译youtube上的up主kudvenkat的javascript tutorial播放单 源地址在此: https://www.youtube.com/watch?v=PMsVM7rjupU& ...