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. Linux系统中文件行末尾出现^M的原因及解决办法

    不同系统,有不同的换行符号: 在windows下的文本文件的每一行结尾,都有一个回车('\n')和换行('\r') 在linux下的文本文件的每一行结尾,只有一个回车('\n'); 在Mac下的文本文 ...

  2. 无法优化的O(n!) 算法

    旅行商问题: 有一位旅行商,他需要前往5个城市. 要前往这5个城市,同时要确保旅程最短. 对于每种顺序,他都计算总旅程,再挑选出旅程最短的路线.5个城市有120种不同的排列方式.因此,在涉及5个城市时 ...

  3. OpenStack集成ceph

    openstack组件集成ceph OpenStack集成ceph详细过程可以查看ceph官方文档:ceph document OpenStack Queens版本,1台控制节点controller, ...

  4. Python的os,shutil和sys模块

    *********OS*********** os.sep 可以取代操作系统特定的路径分隔符.windows下为 '\\' os.name 字符串指示你正在使用的平台.比如对于Windows,它是'n ...

  5. String对象常量池

    对象池的主要目的是实现数据的共享处理, 在java之中对象池可以分为两种: 1.静态常量池 :指*.class加载时会自动将此程序之中保存的 字符串.普通的常量.类和方法的信息等全部经行分配 2.运行 ...

  6. 程序员的进阶课-架构师之路(13)-B-树

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/m0_37609579/article/de ...

  7. Centos 6.x Openssh 升级 7.7p1 版本

    OpenSSH 升级 目前在一家金融公司上班,正好赶上金融公司各种暴雷,本人心里慌慌的. 然后就是金融公司要进行的最低的三级等保评测,各种修改系统安全,密码强度.WAF.防火墙等各种. 评测公司对我司 ...

  8. VS #region

    1.C# 预处理指令 #region使您得以在使用Visual Studio代码编辑器的大纲显示功能时指定可展开或折叠的代码块.    #region   name    其中:name      希 ...

  9. 管道符和作业控制、shell变量、环境变量配置文件 使用介绍

    第6周第1次课(4月23日) 课程内容: 8.6 管道符和作业控制 8.7/8.8 shell变量8.9 环境变量配置文件扩展bashrc和bash_profile的区别 http://ask.ape ...

  10. pringBoot-MongoDB 索引冲突分析及解决【华为云技术分享】

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/devcloud/article/detai ...