zoukankan      html  css  js  c++  java
  • [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 100R31547308

  • 相关阅读:
    爬取药智网中的方剂信息
    日报3.13
    数据库添加出错
    Bencode
    一些安全网络协议
    代码质量不重要
    Jordan Peterson
    随身记录的缺点
    Why is Go PANICking?
    go问
  • 原文地址:https://www.cnblogs.com/crab-in-the-northeast/p/luogu-p1305.html
Copyright © 2011-2022 走看看