PAT-Apat甲级题1004(python和c++实现)

news2024/10/5 20:25:10

PTA | 1004 Counting Leaves

1004 Counting Leaves

作者 CHEN, Yue

单位 浙江大学

A family hierarchy is usually presented by a pedigree tree. Your job is to count those family members who have no child.

Input Specification:

Each input file contains one test case. Each case starts with a line containing 0<N<100, the number of nodes in a tree, and M (<N), the number of non-leaf nodes. Then M lines follow, each in the format:

ID K ID[1] ID[2] ... ID[K]

where ID is a two-digit number representing a given non-leaf node, K is the number of its children, followed by a sequence of two-digit ID's of its children. For the sake of simplicity, let us fix the root ID to be 01.

The input ends with N being 0. That case must NOT be processed.

Output Specification:

For each test case, you are supposed to count those family members who have no child for every seniority level starting from the root. The numbers must be printed in a line, separated by a space, and there must be no extra space at the end of each line.

The sample case represents a tree with only 2 nodes, where 01 is the root and 02 is its only child. Hence on the root 01 level, there is 0 leaf node; and on the next level, there is 1 leaf node. Then we should output 0 1 in a line.

Sample Input:

2 1
01 1 02

Sample Output:

0 1

万事开头难,先读题!

家族等级通常由家谱树表示。你的工作是统计那些没有孩子的家庭成员。
输入规范:

每个输入文件包含一个测试用例。每种情况都以包含0<N<100(树中的节点数)和M(<N)(非叶节点数)的行开始。接下来是M行,每行的格式如下:

ID K ID[1] ID[2]. ID[K]

其中ID是表示给定非叶节点的两位数,K是其子节点的数量,后面是其子节点的两位数ID的序列。为了简单起见,让我们将根ID固定为01。

输入以N为0结束。这种情况不得处理。
输出规格:

对于每个测试用例,您应该从根开始计算每个资历级别中没有孩子的家庭成员。数字必须打印成一行,用空格分隔,每行末尾不得有多余的空格。

示例案例表示只有2个节点的树,其中01是根节点,02是唯一的子节点。因此,在根01层上,有0个叶节点;在下一层上,有1个叶节点。然后我们应该在一行中输出0 1。
样品输入:

2 1
01 1 02

输出示例:

0 1

根据题意,我们可以提取到:

        1, 家庭族谱问题 -> 树,树上问题 - >  dfs

        2, 输入分成两行,第一行输入的是树中所有的节点数N,所有非叶子节点数M。此后输入每一个节点对应的子节点数量和编号

        3, 叶子节点的定义、静态树的实现以及dfs的基础实现

        4, 输出要求是每层的无子节点总数,要求两两之间用空格隔开,不允许有多余空格(要求简单将不再单独说明)

题目读完,现在是手搓代码时间!!!

首先,根据题意,本题需要重点关注的数据结构类型是树,重点要求是统计每一层中无子节点的节点数,其实不管是C++还是python,根据题中所涉及的输入类型来构建一棵树终归是一种比较繁琐且难度较大的过程,因此在碰上类似的题目时,除非题中指明需要构建一棵树来解决问题,否则可以采取以下策略构建静态树:

        1, 对于C++,使用vector容器,该容器兼容大部分数据结构的特性,初始化对应大小的vector很多时候可以简化问题:

                vector<int> child[100];

        2, 对于python,可以使用dict+list来解决这一类问题,将父节点视作key,将父节点的所有子节点加入key的value中,作为value列表

                child = {}

以上思想不仅在树上好用,在图上其实也有很大的应用场景,熟练掌握可以减少很多的时间花费。

在有了基本的方向之后,就可以着手开始搓代码了,

首先,对于输入的处理:

c++部分代码:

        使用int类型的变量n和m分别接收对应的变量N与M,定义parent和child_nums接收第二行输入的节点编号和节点的子节点数,随后循环child_nums次,将其余的输入作为子节点数组和父节点关联。

    cin >> n >> m;
    for(int i = 0; i < m; i++)
    {
        cin >> parent >> child_nums;
        for(int j = 0; j < child_nums; j++)
        {
            int kids;
            cin >> kids;
            child[parent].push_back(kids);
        }
    }

python部分思路类似,代码如下:

注:*childs部分为变长数组,用于打包后面的子节点部分,这部分是列表的索引部分的内容,忘记的同学赶紧记起来!

n, m = [int(i) for i in input().split()]
child = {}
for i in range(m):
    child_id, child_num, *childs = input().split()
    child[child_id] = childs

此后,定义相关的变量:

对于C++,初始化的必要变量如下::

        int n, m, max_depth=1;

        int parent, child_nums;

        vector<int> child[100];

        int nums_of_level[101] = {0};

对于python,初始化以下变量:

        nums_of_level = [0] * (n+1) : 每一层的叶子节点数

        is_visited = {} : 已遍历节点,已遍历为True,未遍历不加入

        max_depth = 0 : 最大深度

此后,设计本题核心部分:dfs

对于C++部分,我们可以当前节点,和当前所在层数传进去,首先判断当前层数和最大层数大小关系,根据判断结果更新最大层数;

此后判断当前节点id是否存在子节点,由于传入的时候,我们呢使用的是vector,使用key:value的结构,此时只要        child[node].size()        其结果大于零,则可以判断,当前节点存在子节点,接下来将对其所有子节点进行dfs,其中传入dfs函数得到参数中,除了node需要改变之外,当前深度depth也需要+1;

若该节点        child[node].size()         结果为零,则表明该节点并没有子节点,即此节点为该层的一个叶子节点,更新nums_of_level[depth],

c++部分代码如下:

void dfs(int node, int depth){
    max_depth = max(depth, max_depth);
    if(child[node].size() == 0)
    {
        nums_of_level[depth] += 1;
        return;
    }
    for(unsigned int i = 0; i < child[node].size(); i++)
    {
        dfs(child[node][i], depth + 1);
    }

对于python部分,传入参数同样为当前的节点node和当前深度depth,

进入dfs之后,首先将该节点node的遍历状态改为True,然后比较当前深度和最大深度,根据结果更新最大深度参数,

由于使用dict结构对输入进行存储,python将面临一个比较大的问题,那就是节点id可能并不是连续的,此时就有可能出现        child[node]        报错node不存在的尴尬时刻,换个角度思考,其实这个编号的节点的节点不在的话,直接更新对应的level所对应的数量。

若 child[node] 非空,则循环遍历其中的节点,将其进入dfs中,同样传入参数中depth+1,

python部分代码如下:

def dfs(node, depth):
    global max_depth
    is_visited[node] = True
    max_depth = max(max_depth, depth)
    if node not in child:
        nums_of_level[depth] += 1
        return 
    for c in child[node]:
        if c not in is_visited:
            dfs(c, depth+1)

完整的代码如下:

C++部分:

#include<bits/stdc++.h>
using namespace std;

int n, m, max_depth=1;
int parent, child_nums;
vector<int> child[100];
int nums_of_level[101] = {0};

void dfs(int node, int depth){
    max_depth = max(depth, max_depth);
    if(child[node].size() == 0)
    {
        nums_of_level[depth] += 1;
        return;
    }
    for(unsigned int i = 0; i < child[node].size(); i++)
    {
        dfs(child[node][i], depth + 1);
    }

}

int main(){
    cin >> n >> m;
    for(int i = 0; i < m; i++)
    {
        cin >> parent >> child_nums;
        for(int j = 0; j < child_nums; j++)
        {
            int kids;
            cin >> kids;
            child[parent].push_back(kids);
        }
    }
    dfs(1, 1);
    printf("%d", nums_of_level[1]);
    for(int i = 2; i <= max_depth; i++)
    {
        printf(" %d", nums_of_level[i]);
    }
    return 0;
}

python部分代码:

n, m = [int(i) for i in input().split()]
child = {}
for i in range(m):
    child_id, child_num, *childs = input().split()
    child[child_id] = childs

nums_of_level = [0] * (n+1)
is_visited = {}
max_depth = 0
def dfs(node, depth):
    global max_depth
    is_visited[node] = True
    max_depth = max(max_depth, depth)
    if node not in child:
        nums_of_level[depth] += 1
        return 
    for c in child[node]:
        if c not in is_visited:
            dfs(c, depth+1)
dfs("01", 0)

print(" ".join(str(i) for i in nums_of_level[0:max_depth + 1]))

最后附上AK截图:

C++:

python:

写在后面:

        本题难度适中,只是简单的考察dfs的应用和静态树的构建以及叶子节点的概念,在处理时应该要小心谨慎!题主在用C++解题时就是因为在测试代码阶段一个多余输入未删除,白白浪费大好时光。。。。请各位一定要引以为鉴!莫要因为题目大意就掉以轻心!

        最后,如果对本题有更好的见解,或者是题主的叙述让你感到困惑、存在不合理的地方,请在评论区交流,欢迎斧正!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1428487.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【超详细教程】2024最新Pytorch安装教程(同时讲解安装CPU和GPU版本)

目录 一、前言 二、pytorch简介 三、安装准备工作 3.1、下载Anaconda 四、判断是否有NVIDIA显卡 五、安装pytorch-CPU版本 六、安装pytorch-GPU版本 6.1、查看CUDA显卡驱动版本 6.2、安装CUDA 6.3、安装CuDNN&#xff08;加速器&#xff09; 6.4、安装pytorch-GPU 七…

瑞_23种设计模式_原型模式

文章目录 1 原型模式&#xff08;Prototype Pattern&#xff09;原型模式的结构 2 实现3 案例3.1 需求3.2 设计3.3 代码实现3.3.1 浅克隆代码实现3.3.2 深克隆代码实现 3.4 总结 &#x1f64a; 前言&#xff1a;本文章为瑞_系列专栏之《23种设计模式》的原型模式篇。本文中的部…

通用缓存SpringCache

概述 在项目中&#xff0c;我们通常会把高频的查询进行缓存。如资讯网站首页的文章列表、电商网站首页的商品列表、微博等社交媒体热搜的文章等等&#xff0c;当大量的用户发起查询时&#xff0c;借助缓存提高查询效率&#xff0c;同时减轻数据库压力。 目前的缓存框架有很多:…

【Linux C | 网络编程】netstat 命令图文详解 | 查看网络连接、查看路由表、查看统计数据

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…

深度学习快速入门--7天做项目

深度学习快速入门--7天做项目 0. 引言1. 本文内容2. 深度学习是什么3. 项目是一个很好的切入点4. 7天做项目4.1 第一天&#xff1a;数据整理4.2 第二天&#xff1a;数据处理4.3 第三天&#xff1a;简单神经网络设计4.4 第四天&#xff1a;分析效果与原因4.5 第五天&#xff1a;…

day02.C++命名空间

目录 一、命名空间的作用 二、命名空间的定义 三、命名空间的镶嵌定义 四、命名空间的使用方法 一、命名空间的作用 一个中大型软件往往由多名程序员共同开发&#xff0c;会使用大量的变量和函数&#xff0c;不可避免地会出现变量或函数的命名冲突。当所有人的代码都测试通过…

iOS应用崩溃了,如何通过崩溃手机连接电脑查找日志方法

在iOS应用开发过程中&#xff0c;调试日志和奔溃日志是开发者必不可少的工具。当iOS手机崩溃时&#xff0c;我们可以连接电脑并使用Xcode Console等工具来查看日志。然而&#xff0c;这种方式可能不够方便&#xff0c;并且处理奔溃日志也相当繁琐。克魔助手的出现为开发者带来了…

Day 17------C语言收尾之链表的删除、位运算、预处理、宏定义

链表 空链表&#xff1a; 注意&#xff1a;函数不能返回局部变量的地址 操作&#xff1a; 1.创建空链表 2.头插 3.尾插 4.链表遍历 5.链表的长度 free&#xff1a;释放 删除&#xff1a; 头删 void popFront(struct Node *head) { //1.p指针变量指向首节点 //2.断…

康姿百德床垫价格合理功效好,用科技力量守护您的睡眠健康

现代生活中&#xff0c;优质睡眠的观念已深入人心。人们渐渐认识到&#xff0c;一个舒适的床垫不仅仅是睡眠的工具&#xff0c;更是健康的守护者。很多朋友在选购床垫一掷千金&#xff0c;却找不到一款合适的床垫。康姿百德床垫是专为提升睡眠质量研发的床垫&#xff0c;成为了…

网络安全全栈培训笔记(60-服务攻防-中间件安全CVE复现WeblogicJenkinsGlassFish)

第60天 服务攻防-中间件安全&CVE复现&Weblogic&Jenkins&GlassFish 知识点: 中间件及框架列表: lIS,Apache,Nginx,Tomcat,Docker,Weblogic,JBoos,WebSphere,Jenkins, GlassFish,Jira,Struts2,Laravel,Solr,Shiro,Thinkphp,Sprng,Flask,jQuery 1、中间件-Web…

Portainer访问远程Docker (TLS加密)

前言&#xff1a; docker的2375端口&#xff0c;出于安全性考虑即(Docker Remote API未授权访问漏洞)&#xff0c;是不开放的&#xff0c;如果想要管理远程docker&#xff0c;可以使用TLS机制来进行访问&#xff0c;这里以Portainer访问连接为例 文章参考&#xff1a;https://b…

外卖,也可以“聚合”

文章首发于微信公众号:PenguinPay &#xff0c;欢迎关注。 一、背景 1.1 订单来源 在过去&#xff0c;商家普遍使用传统POS收银软件进行线下店面收银&#xff0c;可以在一定程度上提升收银效率。 之后随着O2O外卖渠道的发展&#xff0c;越来越多的商家选择在线上平台运营门店…

吸猫毛空气净化器哪个好?推荐除猫毛效果好的宠物空气净化器品牌

如今&#xff0c;越来越多的家庭选择养宠物&#xff0c;使家庭变得更加温馨。然而&#xff0c;养宠物可能会带来异味和空气中的毛发增多&#xff0c;这可能会成为一大困扰&#xff0c;并对健康造成问题。 为了不让家里充斥着异味&#xff0c;特别是来自宠物便便的味道&#xf…

DATAX改造支持geometry类型数据同步

数据库使用postgresql安装了postgis插件存储了geometry空间数据&#xff0c;想使用datax做数据同步&#xff0c;但datax本身不支持geometry类型数据&#xff0c;如何改造呢&#xff1f; 1.首先下载已改造支持geometry类型的datax引擎&#xff0c;下载地址 https://download.c…

《区块链简易速速上手小册》第5章:智能合约(2024 最新版)

文章目录 5.1 智能合约的概念5.1.1 智能合约的基础知识5.1.2 主要案例&#xff1a;去中心化金融&#xff08;DeFi&#xff09;平台5.1.3 拓展案例 1&#xff1a;智能合约在供应链管理中的应用5.1.4 拓展案例 2&#xff1a;智能合约在房地产交易中的应用 5.2 智能合约的应用案例…

函数重载你真的了解吗?

1.什么叫函数重载&#xff1f; 函数重载&#xff08;Function Overloading&#xff09;是指在同一个作用域内&#xff0c;允许定义多个具有相同名称但参数列表不同的函数。具体而言&#xff0c;函数重载允许你定义同名的函数&#xff0c;但这些函数应该有不同的参数类型、参数个…

代码随想录算法训练营Day44|完全背包理论基础、518.零钱兑换II、377. 组合总和 Ⅳ

目录 完全背包理论基础 完全背包问题 算法实现 518.零钱兑换II 前言 思路 377. 组合总和 Ⅳ 前言 思路 算法实现 总结 完全背包理论基础 题目链接 文章链接 完全背包问题 有N件物品和一个最多能背重量为W的背包。第i件物品的重量是weight[i]&#xff0c;得到的价值是…

计网——应用层

应用层 应用层协议原理 网络应用的体系结构 客户-服务器&#xff08;C/S&#xff09;体系结构 对等体&#xff08;P2P&#xff09;体系结构 C/S和P2P体系结构的混合体 客户-服务器&#xff08;C/S&#xff09;体系结构 服务器 服务器是一台一直运行的主机&#xff0c;需…

springboot 整合 PowerJob实现定时任务调度

最近项目需要使用定时任务&#xff0c;而使用了PowerJob做任务调度模块&#xff0c;感觉这个框架真香&#xff0c;今天我们就来深入了解一下新一代的定时任务框架——PowerJob&#xff01; 简介 PowerJob是基于java开发的企业级的分布式任务调度平台&#xff0c;与xxl-job一样…

关于破解IDEA后启动闪退的问题

问题描述&#xff1a;2023.1启动不了&#xff0c;双击桌面图标&#xff0c;没有响应。 解决办法&#xff1a; 打开C:\Users\c\AppData\Roaming\JetBrains\IntelliJIdea2023.1\idea64.exe.vmoptions 这个文件。 内容如下所示&#xff1a; 删除红框的数据以后&#xff0c;再登录…