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 }

浙公网安备 33010602011771号