PTA刷题Advanced甲级——1004.Counting Leaves——Day(2)

问题描述

在这里插入图片描述
简单翻译一下题目:
1004.计算叶子个数
一个家庭的层级结构经常被表现为一个家谱树。你的任务是统计这些家庭成员中谁没有孩子。

输入
每个输入文件包含一个测试实例。每个实例开始的一行包含N和M,N指树中的结点个数(0<N<100),M指非叶结点的个数。然后下面有M行,每行的格式如下:
ID K ID[1] ID[2] …ID[K]
ID是一个两位数的数字,表示一个非叶结点。K表示其孩子的数量。随后是一个序列,序列中是该结点的孩子结点的两位数ID。为了简单起见,我们把根结点的ID固定为01。

输出
对于每个测试实例,你应该计算从根结点开始的每一层中没有孩子的家庭成员的个数。数字必须在一行内输出,用空格分隔,在每行结尾不能有多余的空格。
测试样例表示了一个只有两个结点的树,01是根结点,02是它仅有的孩子。因此在根结点01层级,没有叶节点。再下一层级,有一个叶结点。然后我们应该在一行内输出“0 1”。

题目分析

这道题的难度不大,我们完全可以通过数组和结构体来解决,我们把结点声明为一个结构体类型,其数据成员包括其父结点father、是否有孩子结点Nochild以及它所在的层次level(最终我们会根据层次来输出有多少叶子节点)。
然后我们每行输入的第一个ID,都是后续ID的父节点,需要将后续ID的父节点数据成员指向这一ID。并且`层次=父节点层次+1。如果该节点有孩子结点,就将其数据成员Nochild置为0,否则为1.如果为1,则表明这个结点就是一个叶子节点。
最终我们声明一个level数组,level数组中的索引为层数,值为对应层数的叶子节点数。如何求得呢?
我们只需要遍历所有结点:

for v in 所有节点:
	if(v.Nochild==1)//v点没孩子结点
		lev[v.level]++;

代码

#include<cstdio>
#include<cstring>
struct Node
{
 int father;
 int level;
 bool NoChild;
};
Node v[100];
char level[100]="\0";//level记录的是某层叶结点数目,例如level[i]表示第i层叶子节点数目
int main()
{
 int N,M,c,ID,child,MAXLevel=1;//顶点数目,非叶子结点数目,指示某一顶点的孩子节点数目,顶点编号,顶点的孩子顶点,最大层数
    int i,j;
 scanf("%d%d",&N,&M);
 for(i=0;i<100;++i)
 {
  v[i].father=0;//指示父节点
  v[i].level=0;
  v[i].NoChild=1;
 }
 for(i=0;i<M;++i)
 {
  scanf("%d%d",&ID,&c);
  v[ID].NoChild=0;
  for(j=0;j<c;++j)
  {
   scanf("%d",&child);
   v[child].father=ID;
  }
 }
 v[1].level=1;
 for(i=1;i<=N;++i)
  for(j=1;j<=N;++j)
  {
   if(v[j].father==i)
   {
    v[j].level=v[v[j].father].level+1;
    if(v[j].level>MAXLevel)
     MAXLevel=v[j].level;//更新最大层数
   }
  }
    //遍历所有顶点,找出那个所有叶子节点
 for(i=1;i<=N;++i)
  if(v[i].NoChild==1)
   level[v[i].level]++;//找出叶子结点,放入其所在层数位置
 for(i=1;i<MAXLevel;++i)//最大层数和顶点数目无关,所以我们需要单独记录最大层数
     printf("%d ",level[i]);
 printf("%d\n",level[i]);
 return 0;
}

答题用时16min
Q4——finish√

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章