IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 单调栈(附例题) -> 正文阅读

[C++知识库]单调栈(附例题)

何为单调栈

顾名思义,单调栈即满足单调性的栈结构。与单调队列相比,其只在一端进行进出。

将一个元素插入单调栈时,为了维护栈的单调性,需要在保证将该元素插入到栈顶后整个栈满足单调性的前提下弹出最少的元素。

例如,栈中自顶向下的元素为 1 , 3 , 5 , 10 , 30 , 50 1,3,5,10,30,50 1,3,5,10,30,50,插入元素 20 20 20时为了保证单调性需要依次弹出元素 1 , 3 , 5 , 10 1,3,5,10 1,3,5,10,操作后栈变为 20 , 30 , 50 20,30,50 20,30,50

模板

stack<int>st;
while(!st.empty() && a[st.top()]<=a[i])
    st.pop();	//弹出栈顶元素 
ans[i] = st.empty()?0:st.top();	//栈顶就是答案
st.push(i);		//将当前坐标压入栈顶 

例题1

题目描述

给出项数为 n 的整数数列 a 1 … n a_{1 \dots n} a1n?

定义函数 f ( i ) f(i) f(i)代表数列中第 ii 个元素之后第一个大于 a i a_i ai?的元素的下标,即 f ( i ) = min ? i < j ≤ n , a j > a i f(i)=\min_{i<j\leq n, a_j > a_i} f(i)=mini<jn,aj?>ai??。若不存在,则 f ( i ) = 0 f(i)=0 f(i)=0

试求出 f ( 1 … n ) f(1\dots n) f(1n)

输入格式

第一行一个正整数 n n n

第二行 n n n个正整数 a 1 … n a_{1\dots n} a1n?

输出格式

一行 n n n 个整数 f ( 1 … n ) f(1\dots n) f(1n) 的值。

输入

5
1 4 2 3 5

输出

2 5 4 5 0

题目分析

从后往前扫,注意栈中存储的是值对应的坐标,对于每个点:首先弹出栈顶比她小的元素;此时栈顶就是答案;加入这个元素的坐标。

在这里插入图片描述

C++代码

#include<iostream>
#include<stack>
using namespace std;

#define max 100
int a[max], ans[max];
stack<int>st;

int main(){
	int n;
	cin >> n;
	for(int i=1; i<=n; i++)
		cin >> a[i];
	for(int i=n; i>=1; i--){
		while(!st.empty() && a[st.top()]<=a[i])
			st.pop();	//弹出栈顶元素 
		ans[i] = st.empty()?0:st.top();	//栈顶就是答案
		st.push(i);		//将当前坐标压入栈顶 
	}	
	for(int i=1; i<=n; i++)
		cout << ans[i] <<" ";
	return 0;
}

例题2

题目描述
给定一个整型矩阵 map,其中的值只有 0 和 1 两种,求其中全是 1 的所有矩形区域中,最大的矩形区域里 1 的数量。

输入描述
第一行输入两个整数 n 和 m ,代表 n*m 的矩阵

接下来输入一个 n*m 的矩阵

输出描述
输出其中全是 1 的所有矩形区域中,最大的矩形区域里 1 的数量。

示例1
输入

1 4
1 1 1 0

输出

3

示例2
输入

3 4
1 0 1 1
1 1 1 1
1 1 1 0

输出

6

分析

依次遍历每一行,在第k行,统计从k,k-1……,,连续1的个数,记为weight。同时对于每一行依次求weight时,看作直方图,转换为单调栈问题

C++ 代码

#include<iostream>
#include <cstdio>
#include <algorithm>
#include<stack>
using namespace std;
const int N = 100010;

int n, m, MaxArea = 0, val;
int height[N];
stack<int>st;

int main(void) {
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i++) {	
        for (int j = 1; j <= m; j++) {
            scanf("%d", &val);
            height[j] = val ? height[j] + 1 : 0;	//遇到有0的height就归0 
        }
        for (int j = 1; j <= m; ++j) {
            //栈顶元素大 
            while(!st.empty() && height[st.top()] >= height[j]) {
            	int t = st.top();
				st.pop();
            	int left = st.empty() ? 0 : st.top();	//这一块面积左侧坐标,j是右侧坐标 
            	MaxArea = max(MaxArea, (j-left-1)*height[t]);
			}
			st.push(j);
        }
    }
    printf("%d\n", MaxArea);
    return 0;
}
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-07-22 13:57:27  更:2021-07-22 13:59:58 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/1 21:36:56-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码