#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]=&#39;0&#39;;
        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+&#39;0&#39;;
                    now=now*10+i;
                    i=0;
                    break;
                }
            if(i==10&&pos<end) {    //当前递归层走不通了(即我们进入了一个不存在没走过边的节点),且还没有走完所有的边
                pos--;
                now=(ans[pos-n+1]-&#39;0&#39;)*mod+now;
                vis[now]=false;        //消除死胡同的标记,因为如果直接在当前状态走边now的话,会进死胡同,所以回退
                i=now%10+1;
                now/=10;
            }
        }
        ans[end]=&#39;\0&#39;;
        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