4.2.squence_out_stack 出栈序列

题目描述

求解规定序列能否由入栈出栈操作得到

输入:
有若干组数据输入
每组数据中,第一行为两个个整数 n 和 m。n 表示总过程中需要依次从 1~n 入栈,m 表示这组数据有 m 个出栈序列需要判断,当 n=0 且 m=0 时停止。
接下来有行,每行表示一个出栈序列

输出:
对每一个出栈序列,如果能正常出栈,输出Yes,否则输出 No。

sample:

input:
5 2
1 2 3 4 5
5 4 1 2 3
6 1
6 5 4 3 2 1
0 0

output:
Yes
No

Yes

解题思路

本题就是怎么理解这个出栈序列的问题,也就是说什么样的出栈序列是合法的,又怎么判断?模拟?比较?或者其他算法(还不知道的)

可以有一个思路,后面在判断树的生成时也可以用,也就是简单模拟。但是怎么操作呢,大概是检验的思想——该序列在进入的过程中我就用栈来模拟这个过程,怎样才能生成这样的序列?什么时候就明显不能生成这种序列了?

由于本题只能从小到大进栈,输入出栈序列,每输入一个数:只要当前栈顶不是这个数,就一直入栈,然后出栈顶;考查下一个数。

(1)可能是更大的。重复入栈;

(2)与当前栈顶一致。弹出栈顶,说明也就是按这个顺序出栈;

(3)小于当前栈顶。在弹出栈顶之前不可能弹出这个更小的数,所以不可能,可以否决了。

贴源代码

思路清晰之后其实很简单了,但是可能还有一些实现的小问题、细节,需要打磨一下。

比如每个用例结束的一个空行,有点烦,因为第一个和最后一个都没有空格,复制粘贴一遍还不如直接用times来记录次数,后面的每个打个空行。

还需要注意怎么记录之前已经进栈的最大数字,怎么push,怎么pop;当然,只要思路清晰别把自己绕进去了就很简单啦。

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

int main()
{
	int times = 0;
	while (true) {
		times++;
		int n, m;
		cin >> n >> m;
		if (n == 0 && m == 0)
			return 0;
		else {
			if (times != 1) cout << endl;
			stack<int> s;
			while (m--) {
				if (!s.empty()) s.pop();
				int tmp, maxhasinstack = 0;
				bool yesorno = true;
				for (int i = 0; i < n; i++)
				{
					cin >> tmp;
					if (maxhasinstack < tmp)
					{
						int it = maxhasinstack + 1;
						while (it < tmp) {
							s.push(it);
							it++;
						}
						maxhasinstack = tmp;
					}
					else {
						if (tmp != s.top()) {
							yesorno = false;
						}
						else
						{
							if (!s.empty())
								s.pop();
						}
					}
				}
				if (yesorno)
					cout << "Yes\n";
				else
					cout << "No\n";
			}
		}
	}
}


——2022.10.13

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值