#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<queue> #include <vector> #include<map> #include<set> #include<utility> #define js ios::sync_with_stdio(false) #define mes(a,b) memset(a,b,sizeof a) using namespace std; char ans[1000010]; //保存最终的结果 bool vis[1000010]; //标记边是否被走过 int main() { int n; while(scanf("%d",&n),n) { if(n==1) { puts("0123456789"); continue; } mes(vis,0); int mod=pow(10,n-1); int end=mod*10+n-1; for(int i=0;i<n;++i) ans[i]='0'; vis[0]=true; int now=0,i=0,pos=n; //now表示的是当前所处的节点状态(即由n-1位数位构成的整数) while(pos<end) { now%=mod; for(;i<10;++i) if(!vis[now*10+i]) {//当前状态节点还有没有走过的边 vis[now*10+i]=true; ans[pos++]=i+'0'; now=now*10+i; i=0; break; } if(i==10&&pos<end) { //当前递归层走不通了(即我们进入了一个不存在没走过边的节点),且还没有走完所有的边 pos--; now=(ans[pos-n+1]-'0')*mod+now; vis[now]=false; //消除死胡同的标记,因为如果直接在当前状态走边now的话,会进死胡同,所以回退 i=now%10+1; now/=10; } } ans[end]='\0'; puts(ans); } }
用puts 63ms,printf250多ms
如果加一行typedef long long ll;就变为79ms
输出字典序应该在建立在字符串尽量短的基础上
比较好的两个博客:
https://blog.csdn.net/u013480600/article/details/30049093
https://www.cnblogs.com/GraceSkyer/p/5759348.html