背景
话说这是NOI夏or冬令营中的水题...... 做题前明确的是,这题当然<>n皇后/全排列 这里有n列火车将要进站再出站…… 但是,每列火车只有1节---那就是车头……
有n列火车按1到n的顺序从东方左转进站,这个车站是南北方向的,它虽然无限长, 只可惜是一个死胡同,而且站台只有一条轨道, 火车只能倒着从西方出去,而且每列火车必须进站,先进后出。 (某生:不就是个栈吗?每次可以让右侧头火车进栈,或者让栈顶火车出站? 占卜哥:闭嘴!) 就像这样: 出站<——- <——进站 |车| |站| |__| 现在请你按《字典序》输出前20种可能的出栈方案。 注意:这题当然不等于全排列!!!
一个数n N<=20 数据保证不会TLE所以千万不要halt
《字典序》输出前20种答案,每行一种,不要空格
3
123 132 213 231 321
搜索做,每次枚举出栈多少个元素,记录出栈顺序,只需要输出20个,所以不会T
#include<stdio.h> #include<algorithm> #include<queue> #include<string.h> using namespace std; int stack[30],num[30],n,ans;//stack是模拟的当前栈,num是已经出栈的顺序 int dfs(int t,int l,int ri)//t是出了多少个,l是当前栈里有几个,ri是到了第几个点 { int i,k,s[30]; stack[l]=ri; if(ans>=20) return 0; if(ri==n) { ans++; for(i=1;i<t;i++) printf("%d",num[i]); for(i=l;i>=1;i--) printf("%d",stack[i]); printf("\n"); return 0; } for(i=1;i<=l;i++) s[i]=stack[i]; int tt=t; for(k=1;k<=l+1;k++) { for(i=l;i>=k;i--) { num[t++]=stack[i]; } dfs(t,k,ri+1); t=tt; for(i=1;i<=l;i++) stack[i]=s[i]; } return 0; } int main() { int i,ans=0; scanf("%d",&n); dfs(1,1,1); return 0; } 生成全排列判断 #include<stdio.h> #include<iostream> #include<string.h> #include<math.h> #include<string> #include<algorithm> #include<queue> #include<vector> #include<map> #include<set> #define eps 1e-9 #define PI 3.141592653589793 #define bs 1000000007 #define bsize 256 #define MEM(a) memset(a,0,sizeof(a)) #define inf 0x3f3f3f3f #define rep(i,be,n) for(i=be;i<n;i++) typedef long long ll; using namespace std; vector<int>a,b; int book[20]; int check() { MEM(book); int stack[20],top=0; int i,j; for(i=0;i<a.size();i++) { if(top!=0) { if(stack[top-1]>a[i]) return 0; } for(j=1;j<a[i];j++) { if(!book[j]) stack[top++]=j; } book[a[i]]=1; } return 1; } int main() { int i,n,ans=0; cin>>n; for(i=1;i<=n;i++) { a.push_back(i); b.push_back(i); } if(check()) { for(i=0;i<a.size();i++) cout<<a[i]; cout<<endl; ans++; } next_permutation(a.begin(),a.end()); while(a!=b&&ans<20) { if(check()) { for(i=0;i<a.size();i++) cout<<a[i]; cout<<endl; ans++; } next_permutation(a.begin(),a.end()); } return 0; }