[luogu p1305] 新二叉树
新二叉树
题目描述
输入一串二叉树,输出其前序遍历。
输入输出格式
输入格式
第一行为二叉树的节点数 \(n\)。(\(1 \leq n \leq 26\))
后面 \(n\) 行,每一个字母为节点,后两个字母分别为其左右儿子。
空节点用 *
表示
输出格式
二叉树的前序遍历。
输入输出样例
输入样例 #1
6
abc
bdi
cj*
d**
i**
j**
输出样例 #1
abdicj
分析
这道题真的很简单了,首先找根,其次递归左右节点即可。
找根这方面有点技巧,首先根在这些读入的信息中一定只出现了1次,因为根节点不会作为其他节点的左右子节点出现,只会以根的形式出现。也就是只会出现在信息中的第一列一次。
除了根和星号以外,其他的字符一定出现了两次,因为信息要求任何节点都要表示出他的左右节点,哪怕是叶子节点也要表示出来两个星号。因此也会在信息的第一列出现一次。除此以外,除了根节点外,这个节点一定以子节点的形式出现在其他的信息中,也就是出现在信息的第二列或第三列一次。
这样就很简单了,异或是个好东西,同样的数异或的结果是0,这样我们就可以读入一个字符,如果这个字符s[i][j]
不是星号,那么root ^= s[i][j]
。两个同样的数不会影响结果,这样root
的值就直接是根节点了。
然后是递归过程。首先递归函数中有一个参数ch
,然后我们在信息中找到以ch
为父亲节点的那一条信息,如果接下来的不是星号,则递归这条信息的第二个字符和第三个字符,也就是递归ch
的左右节点。当然也可以把if(ch == '*') return ;
放在递归的开头,也可以达到特判星号的目的。
代码
//忘加水印啦~qwq我忘记啥时候开始打的代码了,就不加啦~
#include <iostream>
#include <cstdio>
std :: string s[35];
int n;
char root;
void work(char ch) {
if(ch == '*') return ;
std :: cout << ch;
for(int i = 1; i <= n; i++)
if(s[i][0] == ch) {
work(s[i][1]);
work(s[i][2]);
}
}
int main() {
std :: cin >> n;
for(int i = 1; i <= n; i++) {
std :: cin >> s[i];
for(int j = 0; j < 3; j++)
if(s[i][j] != '*')
root ^= s[i][j];
}
work(root);
return 0;
}
评测结果
AC 100
:R31547308