描述
我们都知道用“左儿子右兄弟”的方法可以将一棵一般的树转换为二叉树,如:
0 0
/ | \ /
1 2 3 ===> 1
/ \ \
4 5 2
/ \
4 3
\
5
现在请你将一些一般的树用这种方法转换为二叉树,并输出转换前和转换后树的高度。
输入
输入包括多行,最后一行以一个#表示结束。
每行是一个由“u”和“d”组成的字符串,表示一棵树的深度优先搜索信息。比如,dudduduudu可以用来表示上文中的左树,因为搜索过程为:0 Down to 1 Up to 0 Down to 2 Down to 4 Up to 2 Down to 5 Up to 2 Up to 0 Down to 3 Up to 0。
你可以认为每棵树的结点数至少为2,并且不超过10000。
输出
对于每棵树,按如下格式输出转换前和转换后树的高度:
Tree t: h1 => h2
其中t是树的编号(从1开始),h1是转换前树的高度,h2是转换后树的高度。
样例输入
dudduduudu
ddddduuuuu
dddduduuuu
dddduuduuu
#
样例输出
Tree 1: 2 => 4
Tree 2: 5 => 5
Tree 3: 4 => 5
Tree 4: 4 => 4
思路:对于原本树的高度,可以模拟深搜过程,d的时候+1,u的时候-1即可。对于转换的二叉树,可以用这样的方式:如果是d,那么下一个结点在二叉树中深度为当前结点+1,如果是u,则下一个结点如果是d的话说明在树中是当前结点左儿子的右兄弟,那么在二叉树中就是当前节点的右儿子,所以设置临时记录深度h为当前节点的左儿子即可。
#include<iostream>
#include<cmath>
#include<stack>
using namespace std;
int main()
{
int cnt = 0;
char t[1000000];
while (cin >> t)
{
if (t[0] == '#')
break;
int nh = 0, h = 0, nh2 = 0, h2 = 0;
stack<int> now;
now.push(0);
for (int i = 0; t[i] != '\0'; i++)
{
if (t[i] == 'd')
{
nh++;//记录树的当前高度
nh2++;//记录二叉树的当前高度
now.push(nh2);//把当前结点入栈
}
else
{
nh--;
nh2 = now.top();//如果下一个是d那么这个结点在二叉树中就是下一个结点的父亲结点
now.pop();//这一结点已经不在路径上了,出栈
}
h2 = max(h2, nh2);
h = max(h, nh);
}
cout << "Tree " << ++cnt << ": " << h << " => " << h2 << endl;
}
return 0;
}