寒假打卡--算法--栈 例题:AcWing 129. 火车进栈

栈其实抽象的来说就是往瓶子里面放糖的一个过程,先放进去的糖要最后才能吃。

 

栈的定义
栈(stack)是限定仅在表尾进行插入或者删除的线性表。对于栈来说,表尾端称为栈顶(top),表头端称为栈低(bottom)。不含元素的空表称为空栈。因为栈限定在表尾进行插入或者删除,所以栈又被称为后进先出的线性表(简称LIFO:Last in, First out.结构)。
 

栈的逻辑定义、特点及运算:

栈是限定在表的一端进行插入和删除的运算的线性表,通常将插入、删除的一端称为栈顶,另一端称为栈底。不含元素的空表称为空栈。栈的操作具有先进后出或后进先出的特点。栈的运算主要有置空栈、判栈空、判栈满、进栈、退栈、和取栈顶元素6种。

基本概念

栈作为一种数据结构,是一种只能在一端进行插入和删除操作的特殊线性表。它按照先进后出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来)。栈具有记忆作用,对栈的插入与删除操作中,不需要改变栈底指针。

栈是允许在同一端进行插入和删除操作的特殊线性表。允许进行插入和删除操作的一端称为栈顶(top),另一端为栈底(bottom);栈底固定,而栈顶浮动;栈中元素个数为零时称为空栈。插入一般称为进栈(PUSH),删除则称为退栈(POP)。栈也称为先进后出表。

栈可以用来在函数调用的时候存储断点,做递归时要用到栈!

例题:

这里有 n 列火车将要进站再出站,但是,每列火车只有 1 节,那就是车头。

这 n 列火车按 1 到 n 的顺序从东方左转进站,这个车站是南北方向的,它虽然无限长,只可惜是一个死胡同,而且站台只有一条股道,火车只能倒着从西方出去,而且每列火车必须进站,先进后出。

也就是说这个火车站其实就相当于一个栈,每次可以让右侧头火车进栈,或者让栈顶火车出站。

车站示意如图:

            出站<——    <——进站
                     |车|
                     |站|
                     |__|

现在请你按《字典序》输出前 20 种可能的出栈方案。

输入格式

输入一个整数 n,代表火车数量。

输出格式

按照《字典序》输出前 20 种答案,每行一种,不要空格。

数据范围

1≤n≤20

输入样例:

3

输出样例:

123
132
213
231
321
难度:简单
时/空限制:1s / 64MB
总通过数:2854
总尝试数:5033
来源:《算法竞赛进阶指南》
算法标签

解题思路 :

由题目可以知道,火车栈存在两种情况,要么出栈,要么进栈。

于是我们模拟一下样例:

n = 3
第一种情况:
    1. 1 进栈
    2. 1 出栈
    3. 2 进栈
    4. 2 出栈
    5. 3 进栈
    6. 3 出栈
    输出顺序:1 2 3
第二种情况:
    1. 1 进栈
    2. 1 出栈
    3. 2 进栈
    4. 3 进栈
    5. 3 出栈
    6. 2 出栈
    输出顺序:1 3 2
······

ac代码

#include<bits/stdc++.h>

using namespace std;

const int MAXN = 30 ;

int cnt=20 , t1 , t2 ;
int n , s3 = 1;
int s1[MAXN],s2[MAXN];
 

void dfs()
{	
	if( !cnt )
		return ;
	if( t1 == n )
	{
		for( int i = 1 ; i < t1 ;i ++ )
		{
			cout << s1[i] ;
		}
		cout << s1[ t1 ] << endl ;
		cnt --;
		return ;
	}
	if( t2 > 0 )
	{
		
		s1 [ ++ t1 ] = s2 [ t2 -- ] ;
		dfs();
		s2 [ ++ t2 ] = s1 [ t1 -- ];
		
	}
	
	if( s3 <= n)
	{
		s2[ ++t2 ] = s3 ++ ;
		dfs();
		s3 -- ;
		t2 -- ; 
	}
	
	
}
int main()
{

	cin>>n;
	
	dfs();
	
	return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值