---
tags: uva
---
# Uva11147 - KuPellaKeS BST
## 題目大意
KuPellaKeS BTS 是一種 BTS 但遵守以下規則:
1. 左子樹與右子樹的差要最小
2. 若左子樹與右子樹的差相同時,左子樹越大越優先
3. 左右子樹也都皆為 KuPellaKeS BTS
並將此樹以文字輸出,例:
1. node 5 底下有 3,6 這兩個 node 則表示為 5(3,6)
2. node 5 底下只有一個 node 3 表示為 5(3)
3. node 5 底下沒有任何子 node 表示為 5
## 重點觀念
## 分析
- 先將輸入進來的數列排序
- 再將每個 index 到前面的加總紀錄起來
- 先將 l,r 定為 0 與 n-1
- 用 dfs 跑出結果
- 可以從區間的總和算出左右子樹加總出來的值
- 若遇到重複的數字則跳過判斷
## 程式題目碼
```cpp=
#include <algorithm>
#include <iostream>
using namespace std;
#define N 1005
int node[N], sum[N];
void dfs(int l, int r) {
if (l > r) {
return;
}
int root = l, min_diff = INT32_MAX, max_left = INT32_MIN;
for (int i = l; i <= r; i++) {
if (i != r && node[i] == node[i + 1]) {
continue;
}
int left = (i - 1 < 0 ? 0 : sum[i - 1]) - (l - 1 < 0 ? 0 : sum[l - 1]);
int right = sum[r] - sum[i];
int diff = abs(right - left);
if (diff < min_diff) {
root = i, min_diff = diff, max_left = left;
}
if (left > max_left && diff == min_diff) {
root = i, max_left = left;
}
}
cout << node[root];
if (l != r) {
cout << "(";
dfs(l, root - 1);
if (root != l && root != r) {
cout << ",";
}
dfs(root + 1, r);
cout << ")";
}
}
int main() {
int t;
cin >> t;
for (int i = 1; i <= t; i++) {
int n;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> node[i];
}
sort(node, node + n);
sum[0] = node[0];
for (int i = 1; i < n; i++) {
sum[i] = sum[i - 1] + node[i];
}
cout << "Case #" << i << ": ";
dfs(0, n - 1);
cout << endl;
}
return 0;
}
```