题目链接:http://poj.org/problem?id=1780
本题中给出一个位数n,要求给出一个10^n+n-1位数的数,要求每个n位的数都要在里面出现,一个n位的数一共有10^n种,我们容易想到每一位其实都代表一个数,然后最后一个数与之后的n-1位数都成n位的数。第一位的数与之后的五位数是组成一种密码,之后的数的首部n-1位数都与前面的数尾部n-1位数相连,这种类似“首尾相连”的情况很容易让人想到欧拉回路。但是10^6深度dfs会爆栈,所以考虑手写栈。
代码如下:
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 #include <cmath> 6 #include <vector> 7 #include <set> 8 #include <queue> 9 #include <map> 10 using namespace std; 11 12 #define MP make_pair 13 #define ll long long 14 #define inf 0x3f3f3f3f 15 #define maxn 100010 16 #define maxm 1000010 17 int ten[]={1,10,100,1000,10000,100000,1000000}; 18 struct Edge{ 19 int v,nxt; 20 bool vis; 21 }e[maxm]; 22 int head[maxn],esz; 23 void init(){esz=0;memset(head,-1,sizeof(head));} 24 void addedge(int u,int v){ 25 e[esz].v=v,e[esz].nxt=head[u]; 26 e[esz].vis=false; 27 head[u]=esz++; 28 } 29 int st[maxm],top; 30 int ans[maxm]; 31 int main(){ 32 //freopen("out","w",stdout); 33 int n,m; 34 while(~scanf("%d",&n) && n){ 35 if(n==1){puts("0123456789");continue;} 36 init(); 37 for(int i=0;i<ten[n-1];++i){ 38 int x = i%ten[n-2]; 39 for(int j=9;j>=0;--j){ 40 addedge(i,x*10+j);//扩展新的边 41 } 42 } 43 top=0; 44 int sz=0; 45 st[top++]=0; 46 while(top){ 47 int u = st[--top]; 48 bool f=false; 49 for(int i=head[u];i!=-1;i=e[i].nxt){ 50 int v = e[i].v; 51 if(e[i].vis) continue; 52 e[i].vis = true; 53 st[top++]=u; 54 st[top++]=v; 55 f=true; 56 break; 57 } 58 if(f==false) ans[sz++]=u; 59 } 60 for(int i=0;i<n-2;++i) ans[sz++]=0; 61 //for(int i=sz-1;i>=0;--i) printf("%d ",ans[i]); puts(""); 62 for(int i=sz-1;i>=0;--i) printf("%d",ans[i]%10); 63 puts(""); 64 } 65 return 0; 66 }