https://vjudge.net/problem/19105/origin
题意:给出一个中序遍历和一个后序遍历,构建树,然后求出从根节点到哪个叶子节点的值最小;
思路: 题并不难,主要是不知道数的数目进行数的一整行输入;
实现数的一整行输入:
代码可以写成:
int ReadLine(T* data_array) {
string str_line;
if (!getline(cin, str_line)) {
return 0;
} else {
stringstream ss(str_line);
int index = 0;
T temp;
while(ss >> temp) {
data_array[index++] = temp;
}
return index;
}
}
之后进行操作就容易多了:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define INF 0x3f3f3f3f
const int maxn = 100000 + 10;
template<typename T>
int ReadLine(T* data_array) {
string str_line;
if (!getline(cin, str_line)) {
return 0;
} else {
stringstream ss(str_line);
int index = 0;
T temp;
while(ss >> temp) {
data_array[index++] = temp;
}
return index;
}
}
typedef long long ll;
int in[maxn];
int post[maxn];
struct Node
{
int left;
int right;
int flag;
int sum;
}tree[maxn];
struct SS
{
int x;
int sum;
}a[maxn];
int build(int in_low,int in_high,int post_low,int post_high)
{
if(post_low >= post_high)
return 0;
int root = post[post_high - 1];
int p = in_low;
while(in[p] != root)
p ++;
int cnt = p - in_low;
tree[root].left = build(in_low,p, post_low,post_low + cnt);
tree[root].right = build(p + 1,in_high, post_low+cnt,post_high - 1);
return root;
}
int len;
void solve(int root)
{
if(root == 0)
return ;
if(tree[root].left == 0 && tree[root].right == 0)
{
a[len].x = root;
a[len ++].sum = tree[root].sum;
tree[root].flag = 1;
return;
}
if(tree[root].left)
tree[tree[root].left].sum = tree[root].sum +tree[root].left;
if(tree[root].right)
tree[tree[root].right].sum = tree[root].sum +tree[root].right;
solve(tree[root].left);
solve(tree[root].right);
}
int main()
{
while(ReadLine(in))
{
len = 0;
int n = ReadLine(post);
memset(tree,0,sizeof(tree));
build(0,n,0,n);
tree[post[n - 1]].sum = post[n - 1];
solve(post[n - 1]);
int ans = 0;
for(int i = 0; i < len; i ++)
{
if(a[i].sum < a[ans].sum)
{
ans = i;
}
}
cout << a[ans].x << endl;
}
return 0;
}