-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy path1095.cc
77 lines (65 loc) · 1.83 KB
/
1095.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
//Name: Trees Made to Order
//Level: 3
//Category: 数論,二分木,順序付け,再帰
//Note:
/*
* まず必要な葉の数を求め、次に左半分の木、右半分の木の順番で決定していく。
* 構造は再帰的だが、左半分、右半分が具体的にどういう値になるかを計算するのが大変。
*/
#include <iostream>
#include <vector>
using namespace std;
vector<int> pat;
string gentree(int num) {
if(num == 0) return "";
//Determine number of leaves
int lb, ub = 0;
int leaves = 0;
while(true) {
if(ub >= num) break;
lb = ub+1;
++leaves;
ub += pat[leaves];
}
int lb1 = lb;
//Determine left tree
int lleaves = 0;
ub = lb + pat[lleaves]*pat[leaves-1-lleaves]-1;
while(true) {
if(ub >= num) break;
lb = ub+1;
++lleaves;
ub += pat[lleaves]*pat[leaves-1-lleaves];
}
int lb2 = lb;
int rleaves = leaves-1-lleaves;
int leftidx = (num-lb2) / pat[rleaves];
int rightidx = (num-lb2) % pat[rleaves];
int loffset = 0, roffset = 0;
for(int i = 0; i < lleaves; ++i) loffset += pat[i];
for(int i = 0; i < rleaves; ++i) roffset += pat[i];
string left = gentree(leftidx + loffset);
string right = gentree(rightidx + roffset);
if(left.size() > 0) left = "(" + left + ")";
if(right.size() > 0) right = "(" + right + ")";
return left + "X" + right;
}
int main() {
pat.push_back(1);
pat.push_back(1);
int total = 0;
for(int n = 2; ; ++n) {
int cnt = 0;
for(int i = 0; i < n; ++i) cnt += pat[i]*pat[n-i-1];
pat.push_back(cnt);
total += cnt;
if(total >= 500000000) break;
}
while(true) {
int N;
cin >> N;
if(!N) break;
cout << gentree(N) << endl;
}
return 0;
}