Sliding Window
Time Limit: 12000MS   Memory Limit: 65536K
Total Submissions: 73426   Accepted: 20849
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

题目大意:

给你长度为n的数列,要你输出1..k, 2..k+1, 3..k+2, ...区间的最大值和最小值。

单调队列经典题。

维护单调不减序列和单调不增序列的下标,这样队首就分别是最小值和最大值的下标。

以单调不减序列举例:

每次向后移动,先删除队尾元素直至小于等于新元素。贪心的思想,之前队尾元素如果比它大,那该队尾元素永远不可能成为某个区间的最小值。

再判断队首元素是否在k区间内。

单调不增序列同理。

单调队列可以用deque写。

对这两个队列考虑,(平摊分析)每个元素最多入队出队两次。复杂度O(n)。

所以TLE总是让人觉得僵硬。On, 1e6, T???

其实是io太慢了。

scanf printf 相对cin cout 来说确实快了,但这个可是1e6+2e6啊 。。 ̄へ ̄

第一次真正明白输入输出挂的含义。

scanf printf 其实就是对putchar getchar 等函数的封装,功能强大但臃肿。所以,要用一些速度比scanf快,但功能比putchar全面的函数取而代之。

输入输出挂(正负整数)。

template <class T>
inline bool scan_d(T &ret)
{
char c;
int sgn;
if (c = getchar(), c == EOF)
{
return ; //EOF
}
while (c != '-' && (c < '' || c > ''))
{
c = getchar();
}
sgn = (c == '-') ? - : ;
ret = (c == '-') ? : (c - '');
while (c = getchar(), c >= '' && c <= '')
{
ret = ret * + (c - '');
}
ret *= sgn;
return ;
} template <class T>
inline void print_d(T x)
{
if(x < )
{
putchar('-'); x = -x;
}
if (x > )
{
print_d(x / );
}
putchar(x % + '');
}

由上面的代码可以看出,输出一个整数的复杂度并不是o1的,取决于输出数的位数,是o(m),m是常数。如果数是int,n又很大(1e6),复杂度其实是o(mn),用printf的话可以当成onlogn+算了,t也不奇怪吧。

不过该挂对C++极度无感(不知道为啥。。),对G++就很真实了。从下图来说,scanf用c++会快一点,不过真遇到大量输出,g++&挂是最佳选择,所以忘了c++吧。

AC代码:

#include <cstdio>
#include <queue>
#include <deque>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <string>
#include <iostream>
typedef long long ll;
const int maxn=; template <class T>
inline bool scan_d(T &ret)
{
char c;
int sgn;
if (c = getchar(), c == EOF)
{
return ; //EOF
}
while (c != '-' && (c < '' || c > ''))
{
c = getchar();
}
sgn = (c == '-') ? - : ;
ret = (c == '-') ? : (c - '');
while (c = getchar(), c >= '' && c <= '')
{
ret = ret * + (c - '');
}
ret *= sgn;
return ;
} template <class T>
inline void print_d(T x)
{
if(x < )
{
putchar('-'); x = -x;
}
if (x > )
{
print_d(x / );
}
putchar(x % + '');
} int arr[maxn+];
int temp[maxn+];
int ans[maxn][]; int cmp(int x,int y)
{
return arr[x]<arr[y];
} int main()
{
int n,k;
scanf("%d%d",&n,&k);
for(int i=;i<=n;i++)
scan_d(arr[i]); std::deque<int> incq;//单调不减序列
std::deque<int> decq;//单调不增序列 for(int i=;i<=k;i++)
temp[i]=i;
std::sort(temp+,temp++k,cmp);
for(int i=;i<=k;i++)
{
incq.push_back(temp[i]);
decq.push_front(temp[i]);
}
ans[][]=arr[incq.front()];
ans[][]=arr[decq.front()]; for(int i=k+;i<=n;i++)
{
while(!incq.empty())
{
if(incq.front()+k-<i)
incq.pop_front();
else
break;
}
while(!incq.empty())
{
if(arr[incq.back()]>arr[i])
incq.pop_back();
else
break;
}
incq.push_back(i);
while(!decq.empty())
{
if(decq.front()+k-<i)
decq.pop_front();
else
break;
}
while(!decq.empty())
{
if(arr[decq.back()]<arr[i])
decq.pop_back();
else
break;
}
decq.push_back(i);
ans[i-k+][]=arr[incq.front()];
ans[i-k+][]=arr[decq.front()];
} for(int i=;i<=n-k+;i++)
{
if(i==)
print_d(ans[i][]);
else
{
putchar(' ');
print_d(ans[i][]);
}
}
putchar('\n');
for(int i=;i<=n-k+;i++)
{
if(i==)
print_d(ans[i][]);
else
{
putchar(' ');
print_d(ans[i][]);
}
}
putchar('\n'); return ;
}

poj 2823 Sliding Windows (单调队列+输入输出挂)的更多相关文章

  1. POJ 2823 Sliding Window + 单调队列

    一.概念介绍 1. 双端队列 双端队列是一种线性表,是一种特殊的队列,遵守先进先出的原则.双端队列支持以下4种操作: (1)   从队首删除 (2)   从队尾删除 (3)   从队尾插入 (4)   ...

  2. poj 2823 Sliding Window (单调队列入门)

    /***************************************************************** 题目: Sliding Window(poj 2823) 链接: ...

  3. POJ 2823 Sliding Window (单调队列)

    单调队列 加了读入挂比不加更慢.... 而且这份代码要交c++ 有大神G++跑了700ms..... orzorzorz #include<iostream> #include<cs ...

  4. 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 ...

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

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

  6. POJ 2823 Sliding Window 题解

    POJ 2823 Sliding  Window 题解 Description An array of size n ≤ 106 is given to you. There is a sliding ...

  7. 洛谷P1886 滑动窗口(POJ.2823 Sliding Window)(区间最值)

    To 洛谷.1886 滑动窗口 To POJ.2823 Sliding Window 题目描述 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口.现在这个从左边开始向右滑动,每 ...

  8. POJ 2823 Sliding Window 【单调队列】

    题目链接:http://poj.org/problem?id=2823 题目大意:给出一组数,一个固定大小的窗体在这个数组上滑动,要求出每次滑动该窗体内的最大值和最小值. 这就是典型的单调队列,单调队 ...

  9. POJ 2823 Sliding Window(单调队列入门题)

      Sliding Window Time Limit: 12000MS   Memory Limit: 65536K Total Submissions: 67218   Accepted: 190 ...

随机推荐

  1. 【MongoDB】用Docker安装一个MongoDB最新版玩玩

    1 安装 本文假设大家已经安装好了docker并能正常使用,所以不讲解如何安装docker了.用docker安装MongoDB最新版本如下: # 从repository查找mongo的相关镜像,结果很 ...

  2. 20191121-7 Scrum立会报告+燃尽图 03

    此作业的要求参见https://edu.cnblogs.com/campus/nenu/2019fall/homework/10067一.小组情况 队名:扛把子 组长:孙晓宇 组员:宋晓丽 梁梦瑶 韩 ...

  3. KubeCon 2019 北美会议完美落幕 | 云原生生态周报 Vol. 29

    作者 | 陈俊.张晓宇.徐迪 业界要闻 KubeCon 2019 北美会议召开 业界最隆重的盛会 KubeCon+CloudNativeCon 今年在圣地亚哥举办,超过 12000 名参会者以及 10 ...

  4. 2019-9-27:渗透测试,metasploit-framework初接触

    初次利用metasploit漏洞利用框架,入侵获取win7获取权限 目标机系统:windows7,无修复补丁 目标ip地址:192.168.20.131 任务:利用ms17-010,永恒之蓝漏洞,获取 ...

  5. 题解-洛谷P2010-回文日期

    原题链接: https://www.luogu.org/problem/P2010 题目简述: 牛牛习惯用8位数字表示一个日期,其中,前4位代表年份,接下来2位代表月份,最后22位代表日期.显然:一个 ...

  6. python-面向对象之封装

    封装 面向对象三大特性: 继承 封装 多态 隐藏对象的属性和实现细节,仅对外提供公共访问方法 广义上的封装 : 把方法和变量都封装在类中 狭义上的封装 : 在类的外部干脆不能调用了 优点 将变化隔离 ...

  7. centos7环境搭建一台mysql服务器启动多个端口

    在一台服务器上启动多个mysql实例,分别用不同的端口号,因centos7版本安装mysql5.7后不存在mysqld_multi .mysqld_safe等命令,做踩坑总结 Mysql多实例实现的3 ...

  8. Block循环引用问题

    根控制器没办法销毁,除非程序退出 从一个控制器跳到另外一个控制器,调用该控制器的pop方法才会销毁该控制器 self是一个强指针 在block中使用self时要注意循环引用的问题 最好将当前block ...

  9. php 图片指定留白叠加缩放

    遇到这样一个需求:原图大小不一,而且留白也大小不一,需要将原图切出来一个核心图,然后将图片左右留白,组成一个其他尺寸的图片.换句话说,原图在新图片中的位置是可以控制的. 这里思路是:先创建一个规定大小 ...

  10. 与karma、angular的第一次亲密接触

    首先要了解什么是karma,karma干嘛用的,它的好朋友jasmine又是啥?这些文章可以帮助你: karma干嘛的? angular与karma1 angular与karma2 看了以上几篇文章之 ...