题目链接:https://vjudge.net/problem/UVA-548
题解:这题是一道典型的二叉树数据结构题,核心在于,由二叉树的中序和后序遍历求先序遍历。解题的方法是,递归地先由后序遍历获得根结点,然后建立左子树和右子树,最后进行先序遍历,再按题目要求对先充遍历进行操作,输出结果。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<sstream>
#include<string>
#include<algorithm>
#include<climits>
using namespace std;
const int maxn = 1e5 + 10;
//BT structure
int b_data[maxn];
int b_left[maxn];
int b_right[maxn];
int root;
int cut = 0;
int in_order[maxn];
int pos_order[maxn];
int build_BT(int r1,int l1,int r2,int l2) {
//end cond
if (r1 > l1)return -1;
//distrbute a root
int root_index = cut++;
int r = pos_order[l2];
b_data[root_index] = r;
int pos_i = r1;
while (in_order[pos_i] != r)pos_i++;
//build left
b_left[root_index] = build_BT(r1, pos_i - 1, r2, r2 + pos_i - 1 - r1);
//build right
b_right[root_index] = build_BT(pos_i + 1, l1, r2 + pos_i - r1, l2 - 1);
return root_index;
}
int value = 0;
int sumb = INT_MAX;
void pre_order(int r,int s) {
if(b_left[r]==-1&&b_right[r]==-1){
s += b_data[r];
if (s < sumb) {
sumb = s;
value = b_data[r];
}
else if (s == sumb) {
value = min(value, b_data[r]);
}
}
if (b_left[r] != -1)
pre_order(b_left[r], s + b_data[r]);
if (b_right[r] != -1)
pre_order(b_right[r], s + b_data[r]);
}
int main() {
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
string s;
while (getline(cin,s)) {
stringstream ss(s);
int n = 0;
int cnt = 0;
root = 0;
cut = 0;
while (ss >> n) {
in_order[cnt++] = n;
}
getline(cin, s);
ss = stringstream(s);
n = 0;
cnt = 0;
while (ss >> n) {
pos_order[cnt++] = n;
}
memset(b_data, 0, sizeof(b_data));
memset(b_left, 0, sizeof(b_left));
memset(b_right, 0, sizeof(b_right));
sumb = INT_MAX;
value = 0;
//build
root = build_BT(0, cnt - 1, 0, cnt - 1);
//pre
pre_order(root,0);
cout << value << endl;
}
}