问题描述
简单翻译一下题目:
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√