POJ 1780和HDU 2894基本一样
这两道题做法完全相同,唯一的区别就是HDU 2894是一个环(其实也不算区别。。)
方法就是:对于每一个长度为n的串,让该串的前n-1位为一个节点,后n-1位为另一个节点这样就确定了这个串。
PS:POJ 1780递归会爆栈的,只好写手工站,第一次写,一开始写的超麻烦,后来借鉴别人的了。。还是蒟蒻。。
View Code
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cstring> 4 #define M 1001000 5 using namespace std; 6 int to[M],head[M],len[M],next[M],top,cnt,n,dk,ans[M]; 7 bool vis[M]; 8 int fc[8]={1,10,100,1000,10000,100000,1000000}; 9 struct STACK 10 { 11 int x,p; 12 }stack[M]; 13 void add(int u,int v,int w) 14 { 15 to[cnt]=v; len[cnt]=w; next[cnt]=head[u]; head[u]=cnt++; 16 } 17 void create() 18 { 19 memset(head,-1,sizeof head); 20 memset(vis,0,sizeof vis); 21 cnt=0; 22 for(int i=0,tmp;i<fc[n-1];i++) 23 { 24 tmp=i%fc[n-2]; 25 for(int j=9;j>=0;j--)//字典序最小 26 add(i,tmp*10+j,i*10+j); 27 } 28 } 29 void euler() 30 { 31 int u,pos; 32 top=2; dk=0; 33 stack[1].x=0; stack[1].p=head[0]; 34 while(top) 35 { 36 u=stack[top-1].x; pos=stack[top-1].p; 37 for(;~pos;pos=next[pos]) 38 if(!vis[pos]) 39 { 40 stack[top-1].p=pos; 41 vis[pos]=true; 42 stack[top].p=head[to[pos]]; stack[top].x=to[pos]; ++top; 43 break; 44 } 45 if(pos==-1)//扫完u了,相当于递归完毕 46 { 47 ans[++dk]=stack[top-1].p; 48 top--; 49 } 50 } 51 } 52 void prt() 53 { 54 for(int i=1;i<n;i++) printf("0"); 55 for(int i=dk-1;i>=2;i--) printf("%d",len[ans[i]]%10); 56 printf("\n"); 57 } 58 void go() 59 { 60 create(); 61 euler(); 62 prt(); 63 } 64 int main() 65 { 66 while(scanf("%d",&n),n) 67 { 68 if(n==1) printf("0123456789\n"); 69 else go(); 70 } 71 return 0; 72 } 73
HDU 2894:http://www.cnblogs.com/proverbs/archive/2012/08/21/2649984.html