栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

scau 19081 树上摘樱桃

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

scau 19081 树上摘樱桃

Description
网易2021校招笔试-算法工程师(正式第一批)

有一棵二叉树,树上的叶子节点定义为“樱桃”。现在需要找出树上有多少个满足如下子结构的“樱桃”串,即一串上刚好有两颗“樱桃”。
简单说,就是某个节点的左右孩子都是叶子节点,即为一个串。
比如如下的一棵树,红框标示的有两个符合要求的结构,答案就是2

  输入格式
第一行两个正整数m, n,空格分开,分别代表总共有树上有多少个节点和树上有多少条边,(2<=m<=100, 1<=n<=100)
下面有n行,每行为3个部分,用空格分割,第一个数字为某非叶子节点的id,
第二个为该边为left还是right,第三个为子节点的id
注意:节点id彼此不会重复,id 1为根节点 
输出格式
一个整数,标示符合要求的结构的数量。
输入样例
10 9
1 left 2
1 right 3
2 left 4
2 right 5
3 right 6
6 left 7
6 right 8
8 left 9
8 right 10
输出样例
2

这道题看着挺好理解的,就是找左右孩子都是叶子结点的结点呗,那么它的判断条件就是if(它有左孩子 && 它有右孩子 && 它的左孩子没有左孩子 && 它的左孩子没有右孩子 && 它的右孩子没有左孩子 && 它的右孩子没有右孩子),满足这个条件,计数器+1。

好了,我们现在知道要找的结点应满足什么条件了,那我们该怎么判断这六个条件是否满足呢?从老师那里发现了一个很巧妙的方法,用二维数组存储结点,t[n][2]={0},全部初始化为0,即n行2列的二维数组,第一列存放左孩子,第二列存放右孩子。当x=1时,若L=t[x][0]==0,说明结点1没有左孩子,若L=t[x][0]!=0,说明结点1有左孩子;若t[L][0]==0,说明结点1的左孩子没有左孩子,若t[L][1]!=0,说明结点1的左孩子有左孩子。这个能明白叭?不明白的话照着上面给的样例和下面的代码段画一画~

现在原理都知道的差不多了吧~接下来就要看递归的了~

就拿样例来说说吧~

第一次在主函数中调用函数dfs(1),从结点1开始深搜。那么我们知道结点1的左孩子是2,右孩子是3。首先搜索dfs(2),那么2的左孩子是4,右孩子是5,再搜索dfs(4),然后4没有左右孩子,满足递归调用的结束条件,返回,搜索dfs(5),结点5也没有左右孩子,返回,搜索dfs(3),3没有左孩子,只有右孩子6……所以最后一次递归调用得到结点8有左右孩子,且它的左右孩子都没有左右孩子,那么计数器ans++。

每当p==0的时候,说明该结点没有左右孩子,那么它必然不是我们所要找的“樱桃”,所以直接结束递归调用,返回上一层。每当深搜dfs( )时,就会进行一次if判断,如果不满足,就继续返回到上一层,直到回到结点1的左孩子。

void dfs(int p)
{
    if(p==0)
        return;
    int lchild,rchild;
    lchild=t[p][0];
    rchild=t[p][1];
    dfs(lchild);
    dfs(rchild);
    if(lchild && rchild && !t[lchild][0] && !t[lchild][1] && !t[rchild][0] && !t[rchild][1])
        ans++;
}

全部代码

#include 

using namespace std;

int t[105][2]={0},n,m,ans=0;

void dfs(int p)
{
    if(p==0)
        return;
    int lchild,rchild;
    lchild=t[p][0];
    rchild=t[p][1];
    dfs(lchild);
    dfs(rchild);
    if(lchild && rchild && !t[lchild][0] && !t[lchild][1] && !t[rchild][0] && !t[rchild][1])
        ans++;
}
int main()
{
    int i,x,y;
    string s;
    cin>>m>>n;
    for(i=1; i<=n; i++)
    {
        cin>>x>>s>>y; //[x][0]存x的左子树,[x][1]存x的右子树
        if(s=="left")
            t[x][0]=y;
        else
            t[x][1]=y;
    }
    dfs(1);
    cout<

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/833003.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号