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