poj 2823 Sliding Windows (单调队列+输入输出挂)
| Time Limit: 12000MS | Memory Limit: 65536K | |
| Total Submissions: 73426 | Accepted: 20849 | |
| Case Time Limit: 5000MS | ||
Description
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
Output
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 (单调队列+输入输出挂)的更多相关文章
- POJ 2823 Sliding Window + 单调队列
一.概念介绍 1. 双端队列 双端队列是一种线性表,是一种特殊的队列,遵守先进先出的原则.双端队列支持以下4种操作: (1) 从队首删除 (2) 从队尾删除 (3) 从队尾插入 (4) ...
- poj 2823 Sliding Window (单调队列入门)
/***************************************************************** 题目: Sliding Window(poj 2823) 链接: ...
- POJ 2823 Sliding Window (单调队列)
单调队列 加了读入挂比不加更慢.... 而且这份代码要交c++ 有大神G++跑了700ms..... orzorzorz #include<iostream> #include<cs ...
- 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 ...
- POJ 2823 滑动窗口 单调队列
https://vjudge.net/problem/POJ-2823 中文:https://loj.ac/problem/10175 题目 给一个长度为 $N$ 的数组,一个长为 $K$ 的滑动窗体 ...
- POJ 2823 Sliding Window 题解
POJ 2823 Sliding Window 题解 Description An array of size n ≤ 106 is given to you. There is a sliding ...
- 洛谷P1886 滑动窗口(POJ.2823 Sliding Window)(区间最值)
To 洛谷.1886 滑动窗口 To POJ.2823 Sliding Window 题目描述 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口.现在这个从左边开始向右滑动,每 ...
- POJ 2823 Sliding Window 【单调队列】
题目链接:http://poj.org/problem?id=2823 题目大意:给出一组数,一个固定大小的窗体在这个数组上滑动,要求出每次滑动该窗体内的最大值和最小值. 这就是典型的单调队列,单调队 ...
- POJ 2823 Sliding Window(单调队列入门题)
Sliding Window Time Limit: 12000MS Memory Limit: 65536K Total Submissions: 67218 Accepted: 190 ...
随机推荐
- K8s & Openshift案例学习
1. openshift排错技巧:https://mp.weixin.qq.com/s?__biz=MzAwMDc2NjQ4Nw==&mid=2663494178&idx=1& ...
- STDN: Scale-Transferrable Object Detection论文总结
概述 STDN是收录于CVPR 2018的一篇目标检测论文,提出STDN网络用于提升多尺度目标的检测效果.要点包括:(1)使用DenseNet-169作为基础网络提取特征:(2)提出Scale-tra ...
- SpringBoot系列之集成Thymeleaf用法手册
目录 1.模板引擎 2.Thymeleaf简介 2.1).Thymeleaf定义 2.2).适用模板 3.重要知识点 3.1).th:text和th:utext 3.2).标准表达式 3.3).Thy ...
- [CSS七分钟系列]都1902年了,还不知道用margin:auto给flex容器内元素分组?
最近看到几篇博文讲解margin:auto在flex容器中的使用,可惜的是大多讲解都浮于页面表现,没深究其中的作用机理,本文在此浅薄对其表现机理做简单探讨. 引子 日常业务迭代过程中,flex已经是前 ...
- NTP服务编译安装报错:/usr/bin/ld: cannot find –lcap
[root@localhost local]# find / -name "*libcap.so*" [root@localhost ntp-4.2.8p13]# cd /usr/ ...
- Gitlab用户信息批量导出
前言 因运维体系中涉及到用户权限管理及统计,需将Gitlab用户数据提取出来并录入到公司内部自建的权限统计平台. 本文将对Gitlab的用户信息数据批量导出进行操作说明! 思路 A)要对数据进行批量的 ...
- 螺旋矩阵II
Given a positive integer n, generate a square matrix filled with elements from 1 to n2 in spiral ord ...
- 【数据结构】之顺序表(C语言描述)
顺序表是线性表的一种,它将元素存储在一段连续的内存空间中,表中的任意元素都可以通过下标快速的获取到,因此,顺序表适合查询操作频繁的场景,而不适合增删操作频繁的场景. 下面是使用 C语言 编写的顺序表的 ...
- if判断语句的总结
1.表达式:关系表达式或逻辑表达式: 2.表达式的运算结果应该是“真”或者“假”: 真:执行该语句: 假:跳过该语句,执行下一条语句: 3.“语句”可以是单语句也可以是复合语句: ...
- CentOS 7 安装 dnsmasq 服务 实现内网DNS
目录 安装 配置 服务管理 测试解析 安装 废话不多述,上来就安装 yum install -y bind-utils dnsmasq 配置 [root@jenkins ~]# rpm -ql dns ...