2021牛客暑期多校训练营2 - K - Stack( 栈 + 拓扑 )

贪心算法与拓扑排序解决数组构造问题
该博客介绍了如何使用贪心策略和栈来模拟数组b的构造过程,并通过拓扑排序找到合法的数组a。文章首先解析题目,阐述了从数组b求解数组a的思路,然后详细解释了贪心模拟栈的操作,包括当b[i]有值和无值时的不同处理方式。接着,博主展示了如何通过拓扑排序确定a数组的值。在代码实现部分,博主提供了C++代码,演示了整个算法流程。最后,博主通过一个样例解释了当无法构造合法a数组时返回-1的原因。
题目链接:点击进入
题目

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

题意

给出 b 数组的求解方法( 根据 a 得到 b ),然后给你若干个 b 数组的值,让你求一个合法的 a 数组

思路

贪心模拟栈运行的过程,从小到大枚举 b 的每个位置。
若是 b [ i ] 这个位置没数,那就入栈一个比栈顶大的数( 我们这里入栈的是下标,意味着 a [ i ] > a [ 栈顶 ] ) ,让 b [ i ] = b [ i - 1 ] + 1 ;
若是 b [ i ] 这个位置有数,那么我们先判断 b [ i ] 与 栈元素个数的关系:
若是 b [ i ] > 栈内元素个数 + 1 ( 也就是往栈内加一个数达不到 b[ i ] ),说明这个 a 数组不存在,因为我们是贪心的放的,若是这样都满足不了 b [ i ] ,只能说它不合法。
若是 b [ i ] <= 栈内元素个数 + 1 ,那么就让栈内元素出栈 ,一直到 栈内元素数 = b [ i ] - 1 ( 因为还要入栈 a [ i ] ),出栈是为了满足构造 b [ i ],同时也意味着出栈的元素代表的值都比 a [ i ] 大,同时出栈结束的栈顶代表的值比 a [ i ] 小。
这个枚举过程下来,我们会得到 a 数组内不同下标对应值之间的大小关系,根据这个大小关系我们可以连边进行拓扑排序( 小的向大的连边,这样拓扑出来的是一个对应值从小到大排列的下标数组 ),对得到的这个下标数组,从前往后对它们对应的值,从小到大赋值即可。

代码
//#pragma GCC optimize(3)//O3
//#pragma GCC optimize(2)//O2
#include<iostream>
#include<string>
#include<map>
#include<set>
//#include<unordered_map>
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include<stack>
#include<algorithm>
#include<iomanip>
#include<cmath>
#include<fstream>
#
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值