129. 火车进栈
这里有 n列火车将要进站再出站,但是,每列火车只有 1 节,那就是车头。
这 n 列火车按 1 到 n 的顺序从东方左转进站,这个车站是南北方向的,它虽然无限长,只可惜是一个死胡同,而且站台只有一条股道,火车只能倒着从西方出去,而且每列火车必须进站,先进后出。也就是说这个火车站其实就相当于一个栈,每次可以让右侧头火车进栈,或者让栈顶火车出站。
车站示意如图:
出站<—— <——进站
|车|
|站|
|__|
现在请你按《字典序》输出前 20种可能的出栈方案。
输入格式
输入一个整数 n,代表火车数量。
输出格式
按照《字典序》输出前 20 种答案,每行一种,不要空格。
数据范围
1≤n≤20
输入样例:
3
输出样例:
123
132
213
231
321
解题思路:
首先考虑怎样将所有的出栈序列模拟出来,再根据字典序排列方式进行排列。当答案不足20个时全输出,当答案大于20个时输出前20个。
实现代码及注释
#include<iostream>
#include<vector>
#include<stack>
using namespace std;
vector<int> st1; //结果状态储存
stack<int> st2; //栈
int cnt=20; //限制只输出前20种
int st3=1; //还未入栈的状态序列
int n;
void dfs()
{
if(cnt==0)
return; //表示前20种已输出完,结束。
if(st1.size()==n) //边界
{
cnt--;
for(int i=0;i<st1.size();i++)
{
printf("%d",st1[i]);
}
printf("\n");
return;
}
if(st2.size()) //执行出栈的操作
{
st1.push_back(st2.top());//向st1中插入栈st2中的顶部元素
st2.pop(); //删除栈st2中的顶部元素
dfs();
st2.push(st1.back()); //恢复
st1.pop_back();
}
if(st3<=n) //执行出栈的操作
{
st2.push(st3); //将st3的第一个元素放入栈st2中
st3++;
dfs();
st2.pop(); //恢复
st3--;
}
return;
}
int main()
{
scanf("%d",&n);
dfs();
return 0;
}