#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

京公网安备 11010502036488号