题目地址:

https://www.acwing.com/problem/content/description/131/

这里有

n

n

n列火车将要进站再出站,但是,每列火车只有

1

1

1节,那就是车头。这

n

n

n列火车按

1

1

1

n

n

n的顺序从东方左转进站,这个车站是南北方向的,它虽然无限长,只可惜是一个死胡同,而且站台只有一条股道,火车只能倒着从西方出去,而且每列火车必须进站,先进后出。也就是说这个火车站其实就相当于一个栈,每次可以让右侧头火车进栈,或者让栈顶火车出站。车站示意如图:

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

现在请你按字典序输出前

20

20

20种可能的出栈方案。

输入格式:
输入一个整数

n

n

n,代表火车数量。

输出格式:
按照字典序输出前

20

20

20种答案,每行一种,不要空格。

数据范围:

1

n

20

1≤n≤20

1n20

每列火车有三个状态,入站前,在站中,已出站。我们考虑按字典序搜索答案,每次搜的时候,尽量让编号小的列车在出站序列的前面。当站里有车的时候,优先将其出站,然后DFS进入下一层;如果站里没车,则只能将新车入站。当已出站序列长度为

n

n

n的时候即得到了一个答案。代码如下:

#include <iostream>
#include <stack>
#include <vector>
using namespace std;

int n;
vector<int> post_stk;
stack<int> in_stk;
int pre_stk = 1;
int cnt;

void dfs() {
  if (cnt == 20) return;

  if (post_stk.size() == n) {
    for (int x : post_stk) printf("%d", x);
    puts("");
    cnt++;
    return;
  }

  if (in_stk.size()) {
    post_stk.push_back(in_stk.top());
    in_stk.pop();
    dfs();
    in_stk.push(post_stk.back());
    post_stk.pop_back();
  }

  if (pre_stk <= n) {
    in_stk.push(pre_stk++);
    dfs();
    in_stk.pop();
    pre_stk--;
  }
}

int main() {
  scanf("%d", &n);
  dfs();
}

时间复杂度

O

(

2

n

)

O(2^n)

O(2n),空间

O

(

n

)

O(n)

O(n)


版权声明:本文为qq_46105170原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/qq_46105170/article/details/125657439