树的转换
总时间限制:5000ms内存限制:65536kB描述
每行是一个由“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是转换后树的高度。样例输入
我们都知道用“左儿子右兄弟”的方法可以将一棵一般的树转换为二叉树,如:
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
//similar to dp
#include <cstdio>
#include <cstdlib>
#include <string>
#include <cstring>
#define maxn 40005//maxn should be bigger than the count of nodes
int main()
{
char chp_temp[maxn];
int ori_depth = 0, fa[maxn] = {0}, m_dep = 0, m_dep2 = 0, dep[maxn] = {0}, chd[maxn] = {0};//dep record bitree depth, chd record the count of children
//ori_depth record current tree depth(not bitree)
int t = 0;
while (true)
{
++t;
scanf("%s", chp_temp);
int len = strlen(chp_temp);
if (!len) //no need (node > 2)
{
printf("Tree %d: 0 => 0\n", t);
continue;
}
if (chp_temp[0] == '#') break;
ori_depth = 0;//init
memset(chd, 0, sizeof(chd));
memset(dep, 0, sizeof(dep));
memset(fa, 0, sizeof(fa));
m_dep = 0;
m_dep2 = 0;
for (int i = 1; i <= len; ++i)
{
char ch = chp_temp[i - 1];
if (ch == 'd')
{
++ori_depth;
if (m_dep < ori_depth) m_dep = ori_depth;
fa[i] = i - 1;
dep[i] = dep[i - 1] + chd[i-1] + 1;
++chd[i - 1];
if (m_dep2 < dep[i]) m_dep2 = dep[i];
}
else if (ch == 'u')
{
--ori_depth;
dep[i] = dep[fa[i-1]];
chd[i] = chd[fa[i-1]];
fa[i] = fa[fa[i-1]];
}
}
printf ("Tree %d: %d => %d\n", t, m_dep, m_dep2);
}
return 0;
}