题目与翻译

1004 Counting Leaves 数树叶 (30分)

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:

每个输入文件包含一个测试用例。每个案例都从一行开始,该行包含0 < n < 100、树中节点的数量和 m (< n)、非叶节点的数量。然后是 m 行,每行格式如下:

  1. 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.

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

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

输入结束时 n 为0。这种情况不能被处理。

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.

示例案例表示一个只有2个节点的树,其中01是根,02是它的唯一子节点。因此,在根01级上,有0个叶节点; 在下一级上,有1个叶节点。那么我们应该在一行中输出01。

Sample Input:

样本输入:

  1. 2 1
  2. 01 1 02

Sample Output:

示例输出:

  1. 0 1

理解与算法

简单地讲,这道题就是在求一棵多叉树的叶子节点的数量,并按照层的顺序打印!如果没有叶子结点就打印0,否则输出叶子结点个数。

粗略地想一想,层序遍历和前序遍历都可以完成,这里用的是深度优先算法,也就是先序遍历。

给出一个样例的示意图:

01是根节点,因为它有一个子节点02所以它不是叶子结点,而02是叶子结点,因此最后的输出为:

  1. 0 1

接下来来实现程序。

处理输入

  1. // 全局变量
  2. vector<int> nodes[100]; // 每个元素代表一个节点链表
  3. int pedigree[100]; // 族谱树中每一层的叶子结点的数量
  4. int pedigree_depth = -1; // 族谱树的最大深度
  5. int main...(省略部分)
  6. int N, M, node, num, child;
  7. // 处理第一行
  8. cin >> N >> M;
  9. // 遍历所有的非叶节点,构建节点链表
  10. for (int i = 0; i < M; ++i) {
  11. cin >> node >> num;
  12. for (int j = 0; j < num; ++j) {
  13. cin >> child;
  14. nodes[node].push_back(child);
  15. }
  16. }

这里用了一个vector的数组来存储每个节点的子节点链表。

遍历族谱树

  1. /**
  2. * 深度优先算法,遍历整个家族树,如果找到叶子结点就加入到全局变量数组中
  3. * @param index 下标
  4. * @param depth 深度
  5. */
  6. void dfs(int index, int depth) {
  7. if (nodes[index].empty()) {
  8. // 如果这个节点没有子节点,那么就是叶子结点
  9. pedigree[depth]++;
  10. // 这个叶子结点的深度如果超过原本记录的最大深度,那么就更新最大深度
  11. pedigree_depth = depth > pedigree_depth ? depth : pedigree_depth;
  12. return;
  13. }
  14. // 遍历该节点的所有子节点
  15. for (int i : nodes[index]) {
  16. // 因为往下走了一层,所以深度加1
  17. dfs(i, depth + 1);
  18. }
  19. }

为了提高效率,不用每次都遍历整个族谱叶子个数的数组,我们可以使用一个全局变量pedigree_length来确定整个数组的长度,提高最后的打印效率。

输出

  1. // 数组默认值为0,这里输出这个数组的全部内容,长度为pedigree_length
  2. cout << pedigree[0];
  3. for (int i = 1; i <= pedigree_depth; ++i) {
  4. cout << " " << pedigree[i];
  5. }

代码实现

  1. #include <iostream>
  2. #include <vector>
  3. using namespace std;
  4. vector<int> nodes[100]; // 每个元素代表一个节点链表
  5. int pedigree[100]; // 族谱树中每一层的叶子结点的数量
  6. int pedigree_depth = -1; // 族谱树的最大深度
  7. /**
  8. * 深度优先算法,遍历整个家族树,如果找到叶子结点就加入到全局变量数组中
  9. * @param index 下标
  10. * @param depth 深度
  11. */
  12. void dfs(int index, int depth) {
  13. if (nodes[index].empty()) {
  14. // 如果这个节点没有子节点,那么就是叶子结点
  15. pedigree[depth]++;
  16. // 这个叶子结点的深度如果超过原本记录的最大深度,那么就更新最大深度
  17. pedigree_depth = depth > pedigree_depth ? depth : pedigree_depth;
  18. return;
  19. }
  20. // 遍历该节点的所有子节点
  21. for (int i : nodes[index]) {
  22. // 因为往下走了一层,所以深度加1
  23. dfs(i, depth + 1);
  24. }
  25. }
  26. int main() {
  27. int N, M, node, num, child;
  28. // 处理第一行
  29. cin >> N >> M;
  30. // 遍历所有的非叶节点,构建节点链表
  31. for (int i = 0; i < M; ++i) {
  32. cin >> node >> num;
  33. for (int j = 0; j < num; ++j) {
  34. cin >> child;
  35. nodes[node].push_back(child);
  36. }
  37. }
  38. // 对族谱树进行深度优先遍历
  39. dfs(1, 0);
  40. // 数组默认值为0,这里输出这个数组的全部内容,长度为pedigree_length
  41. cout << pedigree[0];
  42. for (int i = 1; i <= pedigree_depth; ++i) {
  43. cout << " " << pedigree[i];
  44. }
  45. return 0;
  46. }

PAT Advanced 1004 Counting Leaves的更多相关文章

  1. PAT Advanced 1004 Counting Leaves (30) [BFS,DFS,树的层序遍历]

    题目 A family hierarchy is usually presented by a pedigree tree. Your job is to count those family mem ...

  2. PAT甲1004 Counting Leaves【dfs】

    1004 Counting Leaves (30 分) A family hierarchy is usually presented by a pedigree tree. Your job is ...

  3. PAT A 1004. Counting Leaves (30)【vector+dfs】

    题目链接:https://www.patest.cn/contests/pat-a-practise/1004 大意:输出按层次输出每层无孩子结点的个数 思路:vector存储结点,dfs遍历 #in ...

  4. PAT 甲级 1004 Counting Leaves

    https://pintia.cn/problem-sets/994805342720868352/problems/994805521431773184 A family hierarchy is ...

  5. PAT甲级 1004.Counting Leaves

    参考:https://blog.csdn.net/qq278672818/article/details/54915636 首先贴上我一开始的部分正确代码: #include<bits/stdc ...

  6. PAT 解题报告 1004. Counting Leaves (30)

    1004. Counting Leaves (30) A family hierarchy is usually presented by a pedigree tree. Your job is t ...

  7. PAT 1004 Counting Leaves (30分)

    1004 Counting Leaves (30分) A family hierarchy is usually presented by a pedigree tree. Your job is t ...

  8. 1004 Counting Leaves ——PAT甲级真题

    1004 Counting Leaves A family hierarchy is usually presented by a pedigree tree. Your job is to coun ...

  9. 1004. Counting Leaves (30)

    1004. Counting Leaves (30)   A family hierarchy is usually presented by a pedigree tree. Your job is ...

随机推荐

  1. python 安装相关

    一.安装python 1.官网下载python 1.1 可下载绿色版 2.2 也可下载安装版,安装时可自动安装pip 和 自动配置环境变量 2.手动配置环境变量,我的电脑>属性>高级> ...

  2. Django中ORM的使用

    Django中ORM的使用 ORM orm(object-relation-mapping)对象关系映射,即用对象来表示关系数据库中的表: 类 --> 表, 对象-->一行数据 对象的属性 ...

  3. 开源项目葫芦藤:IdentityServer4的实现及其运用

    目录 前言 签名证书(Signing Credential) 客户端存储(Client Store) 资源存储(Resource Store) 持久化授权存储(Persisted Grant Stor ...

  4. Python将word文档转换成PDF文件

    如题. 代码: ''' #將word文档转换为pdf文件 #用到的库是pywin32 #思路上是调用了windows和office功能 ''' #导入所需库 from win32com.client ...

  5. sqlserver varchar和Nvarchar区别

    sql server中的varchar和Nvarchar有什么区别?   答:varchar(n)长度为 n 个字节的可变长度且非 Unicode 的字符数据.n 必须是一个介于 1 和 8,000 ...

  6. Winform 去掉 最大化 最小化 关闭按钮(不是关闭按钮变灰)终极解决办法

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  7. 【SpringBoot—注解】@requestBody 与@requestparam;@requestBody的加与不加的区别

    一)首先说明xia @requestBody与@requestParam的区别 spring的RequestParam注解接收的参数是来自于requestHeader中,即请求头.都是用来获取请求路径 ...

  8. Linux嵌入式学习-USB端口号绑定

    由于ubuntu USB设备号为从零开始依次累加,所以多个设备每次开机后设备号不固定,机器人每次开机都要蛋疼的按顺序插, 在网上找到一种方法:udev的规则 udev的规则说明,可以参考博客说明:ht ...

  9. Object[] cannot be converted to String[]

    原因: 你应该是想把List数组转 String数组吧! 然后想当然的调用list.toArray()方法. 结果 该方法返回的是Object[]数组,导致类型不匹配! 解决办法: 还在乖乖的用循环吧 ...

  10. 设计模式——从HttpServletRequestWrapper了解装饰者模式

    从一个业务开始 最近项目上紧急需要,为了应付一个不知道啥的安全检测,我们要给系统追加防XSS注入的功能,这里有经验的JavaWeb开发就会想到,用过滤器或者基于项目框架的拦截器来做,但是顺着这个思路下 ...