题目描述

这里有n列火车将要进站再出站……
但是,每列火车只有1节---那就是车头……
描述
有n列火车按1到n的顺序从东方左转进站,这个车站是南北方向的,它虽然无限长,只可惜是一个死胡同,而且站台只有一条股道,火车只能倒着从西方出去,而且每列火车必须进站,先进后出。
(某生:不就是个栈吗?每次可以让右侧头火车进栈,或者让栈顶火车出站?
老师:闭嘴!)
就像这样:
  出站<——-    <——进站
                    |车|
                    |站|
                    |__|
现在请你按《字典序》输出前20种可能的出栈方案。

 

输入

一个整数 n<=20

 

输出

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

 

样例输入

3

 

样例输出

123
132
213
231
321

全排列,然后模拟栈
取前20,所以不会超时
#include<bits/stdc++.h>
#define long long ll
using namespace std;
int n,num=0,a[200],book[200];//a chu 123 ru
int st[200];
int vt[200];
int top=0;
void Out(int a)    //输出外挂
{
if(a>9) Out(a/10);
putchar(a%10+'0');
}
bool suit()
{
    int j=0,top=0;
    for(int i=1;i<=n;i++){
        if(a[j]==i){
            vt[j]=a[j];
            j++;
        }
        else {
            st[++top]=i;
        }
        while(top!=0&&st[top]==a[j]){
            vt[j]=a[j];
            top--;
            j++;
        }
    }
    for(int i=0;i<n;i++){
        if(vt[i]!=a[i]) return 0;
    }
    return 1;
}
void dfs(int step)
{
    if(num==20) return;
    if(step==n&&num<20){
        if(suit()){
            num++;
            for(int i=0;i<n;i++){
               Out(a[i]);
            }
            puts(" ");
        }
        return;
    }
    for(int i=1;i<=n;i++){
        if(book[i]==0){
        book[i]=1;
        a[step]=i;
        dfs(step+1);
        book[i]=0;
        a[step]=0;
        }
    }
    return ;
}
int main()
{
    scanf("%d",&n);
    dfs(0);
    return 0;
}
火车进站
#include<bits/stdc++.h>
using namespace std;
int s[100];
int n,sum;
vector<int>p;
void fun(int x,int num)
{
    s[x]=1;
    if(x!=0)
    p.push_back(x);
    if(num==n){
        for(int i=0;i<p.size();i++){
            if(i==0) printf("%d",p[i]);
            else printf(" %d",p[i]);
        }
        printf("\n");
    }
    for(int i=1;i<=n;i++){
        if(!s[i]){
            fun(i,num+1);
            s[i]=0;
            p.pop_back();
        }
    }
}
int main()
{
    scanf("%d",&n);
    fun(0,0);
    return 0;
}
全排列递归