出栈序列

题意

给出一个正整数N,给出abc,…(n)个字母,依次出栈,进栈,有多少种序列。
输入:N
输出:第一行输出出栈序列个数,接下来每行输出一个序列

分析

深搜,模拟进栈,出栈过程。

void dfs(int index, int n, int l, int o, stack<char> in, queue<char> out) 

index:第几次过程,从0开始
n:n个字母
l:进栈个数 初始0
o:出栈个数 初始0
in:进栈的元素
out:出栈的元素
当进栈个数l大于出栈个数o才能出栈,当进栈个数小于n才能进栈.
当index = n * 2时停止,输出out中的元素。
每次进出栈的过程,栈中元素和出栈元素初始都在参数中。所以当遇到既能出栈又能进栈的过程时,需要将放在后面函数还原回初始过程的参数。代码对应段中有解释。

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[30][30] = {0};
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
ll cal(ll n, ll m) {
	if (m == 0 || m == n)
		return 1;
	if (a[n][m] != 0)
		return a[n][m];
	a[n][m] = cal(n - 1, m) + cal(n - 1, m - 1);
		return a[n][m];
}
bool book[20];
void dfs(int index, int n, int l, int o, stack<char> in, queue<char> out) {
	if (index == 2 * n) {
		while (!out.empty()) {
			cout << out.front();
			out.pop();
		}
		cout << endl;
		return ;
	}
	if (l > o) { // 出栈 
	// 若将出栈函数放进栈函数下面,会导致回溯时,如果当前参数既可以出栈又可以进栈的话,
	// 会先执行进栈函数,进栈函数会将参数的in加入元素,只需要判断是否可以
    // 执行上面的入栈函数,若执行则还原参数的in	
//		if (l < n)
//			in.pop();
		out.push(in.top());
		in.pop();
		dfs(index + 1, n, l, o + 1, in, out);
	}
	if (l < n) { // 进栈 
	// 若将出栈函数放进栈函数下面,会导致回溯时,如果当前参数既可以出栈又可以进栈的话,
	// 会先执行出栈函数,出栈会将参数的进栈in退出栈顶元素,只需要判断是否可以
    // 执行上面的出栈函数,若执行则还原参数的in栈 
		if (l > o) { 
			in.push(out.front());
			out.pop();
		}
		in.push('a' + l);
		dfs(index + 1, n, l + 1, o, in, out);
	}	
}
int main(int argc, char** argv) {
	int n;
	cin >> n;
	stack<char> in;
	queue<char> out;
	cout << cal(2 * n, n) / (n + 1) << endl;
	dfs(0, n, 0, 0, in, out);
	return 0;
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值