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

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_depthis_visited[node] = Truemax_depth = max(max_depth, depth)if node not in child:nums_of_level[depth] += 1return 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] = childsnums_of_level = [0] * (n+1)
is_visited = {}
max_depth = 0
def dfs(node, depth):global max_depthis_visited[node] = Truemax_depth = max(max_depth, depth)if node not in child:nums_of_level[depth] += 1return 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.mzph.cn/news/663445.shtml

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

相关文章

排序(5)——归并排序

六、归并排序 1.简介 归并排序也是一种很经典的排序算法&#xff0c;采用分治的思想方法进行数据的处理。归并讲究的是先拆后合&#xff0c;也就是分治中的分而治之。在拿到一组数据后&#xff0c;程序会将整个数据进行不断拆分直至有序&#xff0c;因为单个元素必然有序&…

教你怎么给接口定义错误码

错误码一般包括三个要素&#xff1a; 前缀标识&#xff1a;区分错误类型&#xff0c;比如请求不合法&#xff0c;还是服务器处理错误。模块标识&#xff1a;区分到底是哪个模块的错误。错误代码&#xff1a;区分具体是什么问题。 从错误码的符号组成上看又分为三类&#xff1…

网络发展历程及SD-WAN的优势

自网络出现以来&#xff0c;经历了不同时期的发展阶段&#xff0c;而SD-WAN作为网络发展的新趋势&#xff0c;以其独特的优势满足了当今企业对于高效、灵活和成本控制的网络需求。 一、网络发展历程 &#xff08;1&#xff09;初始阶段&#xff1a;专线网络 从1980年代到2000…

VBA数据库解决方案第八讲:SQL语句及打开记录集

《VBA数据库解决方案》教程&#xff08;版权10090845&#xff09;是我推出的第二套教程&#xff0c;目前已经是第二版修订了。这套教程定位于中级&#xff0c;是学完字典后的另一个专题讲解。数据库是数据处理的利器&#xff0c;教程中详细介绍了利用ADO连接ACCDB和EXCEL的方法…

flowable 设置自定义属性教程

概述 由于工作需要给flowable工作流设计器添加自定义属性&#xff0c;以满足功能实现。所以这篇文章介绍下用flowable 开源的的flowable-ui 前端添加自定义属性&#xff0c;后端解析属性值的例子。 技术栈 序号技术点名称版本1Flowable6.8.0 使用的是flowable6.8.0 版的代码…

画质和场景双需求下,海信电视U8KL的变与不变

又到一年春节&#xff0c;最近几年大家过年的方式越来越丰富&#xff0c;但是跟家人在一起看春晚依然是主流&#xff0c;电视也是过年不可或缺的家庭成员。 当然&#xff0c;随着大家对生活品质的要求更高&#xff0c;对电视的要求也变得更高了。比如&#xff0c;现在春晚直播…

爬虫笔记(三):实战qq登录

咳咳&#xff0c;再这样下去会进橘子叭hhhhhh 以及&#xff0c;这个我觉得大概率是成功的&#xff0c;因为测试了太多次&#xff0c;登录并且验证之后&#xff0c;qq提醒我要我修改密码才可以登录捏QAQ 1. selenium 有关selenium具体是啥&#xff0c;这里就不再赘述了&#x…

leetcode c++ 超出内存限制

给两个主要原因&#xff0c;这两个原因&#xff0c;如果在递归或者循环里就很容易导致内存超出限制 首先就是误用 如果只是变量的变化实现的话&#xff0c;或者-就可以了&#xff0c;不需要写成AAx的形式&#xff0c;那样会重新开辟一块内存 其次就是值传递 值传递也是会开辟…

在Linux中对Nginx进行安全加固

准备工作 在IP为x.x.x.x的服务器上安装nginx&#xff0c;确保Linux系统为nginx环境。 检查nginx是否配置nginx账号锁定策略 配置nginx账号锁定策略&#xff0c;降低被攻击概率。 第一步&#xff0c;查看nginx的锁定状态。 命令&#xff1a;passwd -S nginx 若结果出现“P…

【gcc】webrtc发送侧计算 丢包率

大神的分析 : 提到: 每当收到cc-feedback或者收到RR-report的时候就能统计出丢包率,在cc-controller中就会调用SendSideBandwidthEstimation::UpdatePacketsLost()去更新丢包率,同时进行码率预估 G:\CDN\rtcCli\m98\src\modules\congestion_controller\goog_cc\send_side_b…

今日arXiv最热NLP大模型论文:像人一样浏览网页执行任务,腾讯AI lab发布多模态端到端Agent

Agent的发展成为了LLM发展的一个热点。只需通过简单指令&#xff0c;Agent帮你完成从输入内容、浏览网页、选择事项、点击、返回等一系列需要执行多步&#xff0c;才能完成的与网页交互的复杂任务。 比如给定任务&#xff1a;“搜索Apple商店&#xff0c;了解iPad智能保护壳Sm…

Qt中的绝对位置与相对位置

在Qt的开发中&#xff0c;有时候需要获取鼠标点击的位置的坐标。在Qt中坐标分为相对坐标和绝对坐标&#xff1b;相对坐标是以控件的左上角为&#xff08;0&#xff0c;0&#xff09;点的坐标系的坐标&#xff0c;绝对坐标是以显示器屏幕的左上角为&#xff08;0&#xff0c;0&a…

蓝桥杯-常用STL(二)

常用STL &#x1f388;1.集合&#x1f388;2.set的基础使用&#x1f52d;2.1引入库&#x1f52d;2.2插入元素&#x1f52d;2.3删除元素&#x1f52d;2.4判断元素是否存在&#x1f52d;2.5遍历元素&#x1f52d;2.6清空 &#x1f388;3.set与结构体 &#x1f388;1.集合 &#x…

【Algorithms 4】算法(第4版)学习笔记 04 - 2.1 初级排序算法

文章目录 前言参考目录学习笔记1&#xff1a;前置说明1.1&#xff1a;全序关系1.2&#xff1a;Comparable API 实现 demo1.3&#xff1a;排序算法模板2&#xff1a;选择排序2.1&#xff1a;内循环实现过程拆解2.2&#xff1a;代码实现2.3&#xff1a;特点3&#xff1a;插入排序…

【kubernetes】集群网络(二):Flannel的VxLan、Host-GW模式

文章目录 1 Pod的IP地址的分配2 CNI3 Flannel3.1 Flannel的安装3.2 VxLan3.3 Host-GW 4 总结 1 Pod的IP地址的分配 当节点上只安装了docker&#xff0c;则会用veth pairdocker0实现单个节点上容器之间的通信&#xff0c;并且这些容器都在同一个IP段&#xff0c;如果不修改&…

(2024,SaFaRI,双三上采样和 DFT,空间特征和频率特征)基于扩散模型的图像空间和频率感知恢复方法

Spatial-and-Frequency-aware Restoration method for Images based on Diffusion Models 公和众和号&#xff1a;EDPJ&#xff08;进 Q 交流群&#xff1a;922230617 或加 VX&#xff1a;CV_EDPJ 进 V 交流群&#xff09; 目录 0. 摘要 3. 方法 3.1 修改数据保真度 3.2 …

JMeter GUI:测试计划和工作台

什么是测试计划&#xff1f; 测试计划是您添加 JMeter 测试所需元素的地方。 它存储运行所需测试所需的所有元素&#xff08;如线程组、计时器等&#xff09;及其相应的设置。 下图显示了测试计划的示例 测试计划是您添加 JMeter 测试所需元素的地方。 它存储运行所需测试…

Modbus协议学习第六篇之基于libmodbus库的示例程序(可以联合Modbus模拟仿真软件进行调试)

前置工作 学了这么多Modbus的知识&#xff0c;如果不进行实际的操作&#xff0c;总感觉懂的不透彻。基于此&#xff0c; 本篇博文就带各位读者来了解下如何通过编写程序来模拟与Modbus Slave仿真软件的通讯。当然了&#xff0c;这里有两个前提&#xff0c;如下&#xff1a; 1.请…

【深度强化学习】Python:OpenAI Gym-CarRacing 自动驾驶 | 提供项目完整代码 | 车道检测功能 | 路径训练功能 | 车辆控制功能

💭 写在前面:本篇是关于 OpenAI Gym-CarRacing 自动驾驶项目的博客,面向掌握 Python 并有一定的深度强化学习基础的读者。GYM-Box2D CarRacing 是一种在 OpenAI Gym 平台上开发和比较强化学习算法的模拟环境。它是流行的 Box2D 物理引擎的一个版本,经过修改以支持模拟汽车…

一键部署幻兽帕鲁服务器免费一年方案

一、背景介绍 简单讲一下历程&#xff0c;幻兽帕鲁从在1月19日上线&#xff0c;24小时内在线人数峰值便突破200万&#xff0c;作为2024年第一款现象级游戏&#xff0c;《幻兽帕鲁》上线后&#xff0c;由于人数太多&#xff0c;频现服务器过载导致游戏卡顿掉线的情况。为了能够…