目录
1.题目描述
这里有 n 列火车将要进站再出站,但是,每列火车只有 1 节,那就是车头。
这n 列火车按 1 到 n 的顺序从东方左转进站,这个车站是南北方向的,它虽然无限长,只可惜是一个死胡同,而且站台只有一条股道,火车只能倒着从西方出去,而且每列火车必须进站,先进后出。
也就是说这个火车站其实就相当于一个栈,每次可以让右侧头火车进栈,或者让栈顶火车出站。
车站示意如图:
出站<—— <——进站
|车|
|站|
|__|
现在请你按《字典序》输出前 20 种可能的出栈方案。
输入格式
输入一个整数 n,代表火车数量。
输出格式
按照《字典序》输出前 20 种答案,每行一种,不要空格。
数据范围
1≤n≤20
输入样例:
3
输出样例:
123
132
213
231
321
2.题目分析
题目分析:题目中火车有两种行为,1是栈外火车按1~n的顺序进栈,2是栈顶的火车出栈。题目要求输出这两种行为组合产生的出栈顺序的前20种,且按字典序排好序。
3.解题思路
若按DFS的方法来做这道题,每一次的状态是出栈元素的确定个数,每一次的选择是行为1,或行为2,问题的边界为出栈的火车顺序全部确定,即出栈元素的个数等于火车的数量n时,然后输出该顺序。因为要求按字典序输出排序,而行为2是将栈外比栈内顺序大的火车加到栈顶上,而行为1是将栈中比栈外顺序小的栈顶的火车出栈,则先进行的是行为1能满足字典序要求。
4.代码实现
station1:存储出栈火车的顺序
station2:存储入栈火车的顺序
station3:模拟入栈火车的序号
cnt:统计已经输出的顺序的个数
#include<iostream>
#include<vector>
#include<stack>
using namespace std;
vector<int> station1;
stack<int> station2;
int station3 = 1;
int cnt = 0;
int n;
void dfs(int t) {
if (cnt == 20) return;
if (t== n) {
for (int i = 0; i < n; i++) {
cout << station1[i];
}
cnt++;
cout << endl;
}
if (!station2.empty()) {
station1.push_back(station2.top());
station2.pop();
dfs(t+1);
station2.push(station1.back());
station1.pop_back();
}
if (station3 <= n) {
station2.push(station3);
station3++;
dfs(t);
station3--;
station2.pop();
}
}
int main() {
cin >> n;
dfs(0);
return 0;
}