2022 10 18 洛谷 P5788 单调栈

 解题思路:维护一个单调递减的栈,每当当前元素大于栈顶,则说明当前元素是第一个大于栈顶元素的元素;此时,将栈内小于当前元素的元素全部弹出,然后将当前元素压入栈顶,维护栈的单调性。

例如:单调栈内是 5 3 2, 当前元素是4(即5 3 2 4...的序列),那么应该将栈内小于当前元素的元素全部弹出,(先将栈顶2弹出,并设大于2的第一个元素是5;然后先将栈顶3弹出,并设大于的第一个元素是5),最后4小于栈顶5,不再弹栈,然后将4压入栈,此时栈内为5 4,继续遍历后面的数字。

#include<iostream>
using namespace std;

const int N = 3e6 + 5;
int num[N];//存放输入的数组 
int stack[N];//单调栈,存的是num数组的下标 
int ans[N];//结果数组,存放的也是num的下标 
int n;

int main()
{
	scanf("%d", &n);
	for (int i = 1; i <= n; i++) scanf("%d", &num[i]);
	//数组从1开始存,便于处理元素 
	int t = 0;//栈顶指针,指向的是栈内下一个被存入的位置 
	
	for (int i = 1; i <= n; i++)
	{
		while (t && num[i] > num[stack[t - 1]])//若当前元素大于栈顶 
		{
			t--;//弹栈 
			ans[stack[t]] = i;//设当前元素为大于栈顶的第一个元素 
		}
		stack[t++] = i;//将当前元素压栈 
	}
	
	for (int i = 1; i <= n; i++) printf("%d ", ans[i]);
	return 0;
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值