POJ 1095

Ref:http://blog.csdn.net/lvlu911/article/details/5425974#

 

 

View Code
 1 //Result:wizmann    1095    Accepted    712K    16MS    G++    1079B
 2 #include <cstdio>
 3 #include <cstdlib>
 4 #include <cstring>
 5 #include <iostream>
 6 #include <algorithm>
 7 
 8 using namespace std;
 9 
10 #define print(x) cout<<x<<endl
11 #define input(x) cin>>x
12 #define SIZE 20
13 
14 int branch[SIZE];
15 int sum[SIZE];
16 
17 void init()
18 {
19     branch[0]=branch[1]=1;
20     sum[0]=0;sum[1]=1;
21     
22     for(int i=2;i<SIZE;i++)
23     {
24         for(int j=0;j<i;j++)
25         {
26             branch[i]+=branch[j]*branch[i-j-1];
27         }
28     }
29     for(int i=2;i<SIZE;i++)
30     {
31         sum[i]+=sum[i-1]+branch[i];
32     }
33 }
34 
35 void slove(int n)
36 {
37     if(n==0) return;
38     if(n==1) printf("X");
39     else
40     {
41         int i,j;
42         for(i=0;i<SIZE;i++)
43         {
44             if(sum[i]>=n) break;
45         }
46         n-=sum[i-1];
47         //i指的是,在此(子)树中,共有多少个节点
48         
49         //由于树的构建是先右后左,所以j表示的是左子树的节点数
50         for(j=0;j<i;j++)
51         {
52             int t=branch[j]*branch[i-j-1];
53             if(t<n) n-=t;
54             else break;
55         }
56         
57         //那么首先是右子树在发生变化,从1到L[n-i-1]。
58         //继续增长,右子树的形态复位为1,而左子树的形态增加1.
59         //因此右子树相当于秒针,左子树相当于分针。
60         //对于s,该树的左子树编号为(s-1)/L[n-i-1]+1,右子树编号为(s-1)% L[n-i-1]+1。
61         if(j)//如果左子树有节点
62         {
63             printf("(");
64             slove(sum[j-1]+(n-1)/branch[i-j-1]+1);
65             printf(")");
66         }
67         printf("X");
68         if(j!=i-1)
69         {
70             printf("(");
71             slove(sum[i-j-2]+(n-1)%branch[i-j-1]+1);
72             printf(")");
73         }
74     }
75 }
76 
77 int main()
78 {
79     int n;
80     init();
81     while(input(n) && n)
82     {
83         slove(n);
84         puts("");
85     }
86     return 0;
87 }

posted on 2012-06-27 21:57  Wizmann  阅读(423)  评论(0)    收藏  举报

导航