PAT 1004 Counting Leaves

来源:互联网 发布:淘宝自定义模块 编辑:程序博客网 时间:2024/05/20 17:08

问题重述:

A family hierarchy is usually presented by a pedigree tree. Your job is to count those family members who have no child.
一个家族的繁衍通常用一棵家族树来表示,你的任务在于计算这其中没有孩子的家族成员的数量。

输入和输出示例:

输入:每个文件包含有一个测试样例,每个测试样例中包含有如下内容:
N: 家族树中的节点总个数
M:家族树中非叶子节点的个数

输出:每一层中叶子节点的个数

Sample Input
2 1
01 1 02
Sample Output
0 1

问题分析:

通过读题,可以较为清晰地看到数据结构与树有关,但是应当怎样构建树值得思考。在一开始,我想到了包括多叉树、左孩子右兄弟结构等等,当时学数据结构时仅存的关于树的记忆都显示出来。但是,当再次分析这道题时,你会发现,这道题考察的是一个父母节点有没有子节点,甚至连子节点的个数都不需要具体确定;也就是说,对于每一个节点而言我只需要知道一个布尔值,即有没有孩子。分析到这里,复杂的数据结构就可以被避免了。于是,我设计了下面的一个节点结构:

typedef struct Tree_Node
{
int child_num ;
int father ;
int level ;
int active ;
}Tree_Node ;

其中child_num表示对是否有孩子的判断,father是对父母节点索引的记录,level是记录该节点所在的层数,active表示该节点是否是处于激活的状态;

具体的算法为,创建节点的数组,并进行初始化。因为题目中fix了根节点的编号,因此可直接对下标为1的节点进行特殊处理。然后完成输入,在每输入一行时,对这一行涉及的节点相关信息进行更新,这其中包括:新节点的激活;新节点的父节点更新;新节点的父节点的child_num的更新;
在输入完成之后,即可以遍历该节点数组,找到每个level中child_num显示为False的节点数目,输出即可;

注意:
我基于上面的方法写出程序进行测试,始终有两个测试点无法通过。通过在网上查阅其他的博文,发现一种错误在于:题目中给定的输入可能是无序的。也就是说,父节点很有可能晚于子节点出现。这一点的重要性体现在level上,因为子节点所在的level是要根据父节点进行更新的,如果父节点的level都无法得到,那子节点也不行。因此,解决的方法在于完成输入后,通过统一的遍历,完成对于level的设定;

收获

刚刚开始刷PAT系列,还是希望提高自己的编程能力,初期的时候这些题目还要花很长的时间,当AC后回过头来看,又有种失望,觉得自己不应该在这些点上卡住很久。希望通过这个博客记录下自己的点点滴滴吧,虽然现在真的很水,但每天都要有一点点的进步。以后一定要好好审题啊!

代码

#include<stdio.h>#include<stdlib.h>#define MAXNUM 100#define End -1#define True 1#define False 0int M ;   // the number of the nodeint N  ;  // the number of the non-leaf nodetypedef struct Tree_Node{        int child_num ;        int father ;        int level ;        int active ;}Tree_Node ;int main(){        Tree_Node TA[MAXNUM] ;        int i , j ;        int a;        int c ;        int pos ;        int number =0 ;        int U[MAXNUM];        scanf("%d%d",&M,&N) ;        TA[0].child_num = End;        TA[0].level = End ;        TA[0].active = False ;        TA[0].father = False ;        TA[1].level = 1 ;        TA[1].active = True ;        TA[1].child_num = End ;        TA[1].father = End ;        for( i = 2 ; i<MAXNUM ; i++){                TA[i].child_num = End ;                TA[i].level = End ;                TA[i].active = False ;                TA[i].father = End ;        }        for(i=0;i<N;i++){                scanf("%d%d",&a,&c);                TA[a].active=True;                for(j=0;j<c;j++){                        scanf("%d",&pos);                        TA[pos].active=True;                        TA[a].child_num = True ;                        TA[pos].father = a ;                }        }        for(i=2;i<MAXNUM;i++){                TA[i].level = TA[TA[i].father].level+1;        }        for(i=0;i<MAXNUM;i++){                U[i]=End;                if(TA[i].level!=End&&TA[i].active==True){                        U[TA[i].level] = 0 ;                }        }        for(i=1;i<MAXNUM;i++){                if(U[i]!=End){                        number++;                }        }        for(i=1;i<MAXNUM;i++){                if(TA[i].active==True&&TA[i].child_num==End){                        U[TA[i].level]++;                }        }        for(i=1;i<number;i++){                printf("%d ",U[i]);        }        printf("%d",U[number]);        return 0 ;}