POJ 1780(欧拉路)

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

posted @ 2012-08-29 17:18  proverbs  阅读(383)  评论(0编辑  收藏  举报