单调栈(G - Sliding Window POJ - 2823 )
题目链接:https://cn.vjudge.net/contest/276251#problem/G
题目大意:给你n和m,然后问你对于(m,n)这中间的每一个数,(i-m+1,i)这个区间的最小值和最大值。
具体思路:单调队列,对于个数的控制,我们通过队列来实现一个模拟的滑动窗口。然后最值的寻找,我们可以通过控制队列保持单调递增或者单调递减来实现。
STL AC代码(耗时:10985s):
#include<iostream>
#include<stack>
#include<cmath>
#include<string>
#include<stdio.h>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
# define inf 0x3f3f3f3f
# define ll long long
const int maxn = 1e6+;
int minn[maxn],maxx[maxn],sto[maxn];
inline int read1()
{
int f=,x=;
char s=getchar();
while(s<'' || s>'')
{
if(s=='-')
f=-;
s=getchar();
}
while(s>='' && s<='')
{
x=x*+s-'';
s=getchar();
}
return x*f;
}
int main()
{
int n,m;
n=read1();
m=read1();
// scanf("%d %d",&n,&m);
deque<int>q1;
deque<int >q2;
int tot=,tmp;
for(int i=;i<=n;i++){
sto[i]=read1();
}
for(int i=; i<=n; i++)
{
while(!q1.empty()&&q1.front()<i-m+)//先判断左边界有没有超出范围
q1.pop_front();
while(!q1.empty()&&sto[i]<sto[q1.back()])//保持队列单调递增
{
q1.pop_back();
}
q1.push_back(i);
if(i>=m)
minn[++tot]=q1.front();
while(!q2.empty()&&q2.front()<i-m+)
q2.pop_front();
while(!q2.empty()&&sto[i]>sto[q2.back()])
{
q2.pop_back();
}
q2.push_back(i);
if(i>=m)
maxx[tot]=q2.front();
}
for(int i=; i<=tot; i++)
{
if(i==)
printf("%d",sto[minn[i]]);
else
printf(" %d",sto[minn[i]]);
}
printf("\n");
for(int i=; i<=tot; i++)
{
if(i==)
printf("%d",sto[maxx[i]]);
else
printf(" %d",sto[maxx[i]]);
}
printf("\n");
return ;
}
数组模拟(耗时:7152ms)AC代码:
#include<iostream>
#include<stack>
#include<cmath>
#include<string>
#include<stdio.h>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
# define inf 0x3f3f3f3f
# define ll long long
const int maxn = 1e6+;
int minn[maxn],maxx[maxn],sto[maxn];
int moni[maxn];
inline int read1()
{
int f=,x=;
char s=getchar();
while(s<'' || s>'')
{
if(s=='-')
f=-;
s=getchar();
}
while(s>='' && s<='')
{
x=x*+s-'';
s=getchar();
}
return x*f;
}
int main()
{
int n,m;
n=read1();
m=read1();
int l=,r=;
int tot=;
for(int i=; i<=n; i++)
{
sto[i]=read1();
}
for(int i=; i<=n; i++)
{
while(l<=r&&moni[l]<i-m+)
l++;
while(l<=r&&sto[i]<sto[moni[r]]){
r--;
}
moni[++r]=i;
if(i>=m)
minn[++tot]=moni[l];
}
l=,r=,tot=;
for(int i=; i<=n; i++)
{
while(l<=r&&moni[l]<i-m+)
l++;
while(l<=r&&sto[i]>sto[moni[r]]){
r--;
}
moni[++r]=i;
if(i>=m)
maxx[++tot]=moni[l];
}
for(int i=; i<=tot; i++)
{
if(i==)
printf("%d",sto[minn[i]]);
else
printf(" %d",sto[minn[i]]);
}
printf("\n");
for(int i=; i<=tot; i++)
{
if(i==)
printf("%d",sto[maxx[i]]);
else
printf(" %d",sto[maxx[i]]);
}
printf("\n");
return ;
}
(我太菜了,,,数组模拟调了半个小时。。)
单调栈(G - Sliding Window POJ - 2823 )的更多相关文章
- Sliding Window POJ - 2823 单调队列模板题
Sliding Window POJ - 2823 单调队列模板题 题意 给出一个数列 并且给出一个数m 问每个连续的m中的最小\最大值是多少,并输出 思路 使用单调队列来写,拿最小值来举例 要求区间 ...
- Sliding Window POJ - 2823
Description An array of size n ≤ 106 is given to you. There is a sliding window of size k which is m ...
- AC日记——Sliding Window poj 2823
2823 思路: 单调队列: 以前遇到都是用线段树水过: 现在为了优化dp不得不学习单调队列了: 代码: #include <cstdio> #include <cstring> ...
- sliding windows (poj 2823) 题解
[问题描述] 给你一个长度为N的数组,一个长为K的滑动的窗体从最左移至最右端,你只能见到窗口的K个数,每次窗体向右移动一位,如下表: [样例输入] 8 3 1 3 -1 -3 5 3 6 7 [样例输 ...
- poj 2823 Sliding Window (单调队列入门)
/***************************************************************** 题目: Sliding Window(poj 2823) 链接: ...
- Codeforces 1107G Vasya and Maximum Profit 线段树最大子段和 + 单调栈
Codeforces 1107G 线段树最大子段和 + 单调栈 G. Vasya and Maximum Profit Description: Vasya got really tired of t ...
- POJ 2823 Sliding Window + 单调队列
一.概念介绍 1. 双端队列 双端队列是一种线性表,是一种特殊的队列,遵守先进先出的原则.双端队列支持以下4种操作: (1) 从队首删除 (2) 从队尾删除 (3) 从队尾插入 (4) ...
- 题解报告:poj 2823 Sliding Window(单调队列)
Description An array of size n ≤ 106 is given to you. There is a sliding window of size k which is m ...
- POJ 2823 Sliding Window(单调队列入门题)
Sliding Window Time Limit: 12000MS Memory Limit: 65536K Total Submissions: 67218 Accepted: 190 ...
随机推荐
- Dubbo学习(二) Dubbo 集群容错模式-负载均衡模式
Dubbo是Alibaba开源的分布式服务框架,我们可以非常容易地通过Dubbo来构建分布式服务,并根据自己实际业务应用场景来选择合适的集群容错模式,这个对于很多应用都是迫切希望的,只需要通过简单的配 ...
- macOS how to install python3
macOS how to install python3 macOS & Python 3.7.2 https://www.python.org/downloads/mac-osx/ http ...
- Delphi开发单机瘦数据库程序要点(后缀cds)
一.概述 Delphi作为Windows下的一种快速开发工具,不仅能开发一般的Windows应用程序,而且还具有强大的数据库应用程序开发功能.Delphi本身提供了对BDE,ODBC,ADO和Inte ...
- springmvc+mybatis 处理时间
项目结构: 一.数据库中time的字段为datetime1. 数据库设计如图 2. addNews.jsp <%@ page language="java" contentT ...
- SpringBoot之mongoTemplate的使用
springboot的版本1.5.17.RELEASE. 1.mongo的IP和端口 在resources下的application.properties中加入如下内容 spring.data.mon ...
- Java多线程相关的
很多小伙伴在学习Java的时候,总是感觉Java多线程在实际的业务中很少使用,以至于不会花太多的时间去学习,技术债不断累积!等到了一定程度的时候对于与Java多线程相关的东西就很难理解,今天需要探讨的 ...
- BZOJ2876 [Noi2012]骑行川藏 【拉格朗日乘数法】
题目链接 BZOJ 题解 拉格朗日乘数法 拉格朗日乘数法用以求多元函数在约束下的极值 我们设多元函数\(f(x_1,x_2,x_3,\dots,x_n)\) 以及限制\(g(x_1,x_2,x_3,\ ...
- 【bzoj3573】 Hnoi2014—米特运输
http://www.lydsy.com/JudgeOnline/problem.php?id=3573 (题目链接) 题意 题意是这道题最大的难点→_→ Solution 沙茶树形dp,考虑一定会存 ...
- 解题:POI 2012 Well
题面 比较明显地能看出二分来,但是检查函数很难写.对于二分出的一个$mid$,我们要让它满足在$m$次操作内令序列中存在一个为零的位置,同时使得任意相邻的两项之差不超过$mid$ 第二项的检查比较好做 ...
- Java入门:Java中获取键盘输入值的三种方法
Java程序开发过程中,需要从键盘获取输入值是常有的事,但Java它偏偏就没有像c语言给我们提供的scanf(),C++给我们提供的cin()获取键盘输入值的现成函数!Java没有提供这样的函数也不代 ...