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 ...
随机推荐
- 关于springboot2.*版本无法加载静态资源
前言 在学习springboot的过程中,发现无法引用静态资源.我使用的是springboot2.2.1版本. 追溯源码,终于解决.并记录下解决思路. 默认加载路径 首先得知道springboot默认 ...
- Alibaba Nacos 学习(一):Nacos介绍与安装
Alibaba Nacos 学习(一):Nacos介绍与安装 Alibaba Nacos 学习(二):Spring Cloud Nacos Config Alibaba Nacos 学习(三):Spr ...
- Django2.0--创建缓存表
创建缓存表 在项目的虚拟环境下(若有),执行:python manage.py createcachetab
- Tensorflow常用函数说明
1.矩阵操作 1.1矩阵生成 这部分主要将如何生成矩阵,包括全0矩阵,全1矩阵,随机数矩阵,常数矩阵等 sess=tf.InteractiveSession() #x=tf.ones([2,3],tf ...
- python常见字符串操作
附: python2.x和python3.x中raw_input( )和input( )区别: 备注:1.在python2.x中raw_input( )和input( ),两个函数都存在,其中区别为r ...
- ExtentTestNGIReporterListener
package com.testng.config; import com.aventstack.extentreports.ExtentReports; import com.aventstack. ...
- 【Android - 组件】之Activity的启动模式
Activity的启动模式目前有四种:standard.singleTop.singleTask 和 singleInstance. 1.standard standard 是标准模式,也是系统的默认 ...
- Java基础部分(11~20)
11."=="和 equals 方法究竟有什么区别? (单独把一个东西说清楚,然后再说清楚另一个,这样,它们的区别自然就出来了,混在一起说,则很难说清楚) ==操作符专门用来比较两 ...
- Chapter 03—Getting Started with graphs
例01:一个简单的例子 一. 图形参数 1. 符号和线条 例02: plot(dose,drugA,type="b",lty=3,lwd=3,pch=1 ...
- js3——表格下拉
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...