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

你可能感兴趣的:(poj)