PAT1004

高效解决家族谱系树计数问题

该题其实算是题目中的简单题,但是没想到竟然有三十分,可能是需要建立比较特别的树结构吧,所以分值相对来说比较高,其实如果看过《算法导论》的朋友应该都有印象,这里的树结构其实就是《算法导论》第三版中137页里提到的分支无限有根树,这里只需要使用“左孩子右兄弟”的方法就可以轻松表示出题目中提到的pedigree tree。题目和源代码结构如下:

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

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.

Output

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
本人的参考代码:
#include "iostream"
using namespace std;


struct LRTree
{
	//int ID;
	int layer;
	int PtrOfLeftChild;
	int PtrOfBrother ;
	//LRTree *PtrOfLeftChild;
	//LRTree *PtrOfBrother;
	LRTree(){layer = 0;PtrOfBrother = 0;PtrOfLeftChild = 0;};
	LRTree(int L,int PB, int PC){layer = L;PtrOfBrother = PB;PtrOfLeftChild = PC;};
};

int NoChildMemberCount[102] = {0};
int MaxLayerNum = 0;
void MemberInput(LRTree PedigreeTree[])
{
	int ID;
	int K;
	int i;
	cin>>ID>>K;
	cin>>PedigreeTree[ID].PtrOfLeftChild;
	ID = PedigreeTree[ID].PtrOfLeftChild;
	for(i = 1;i<K;i++)
	{
		cin>>PedigreeTree[ID].PtrOfBrother;
		ID = PedigreeTree[ID].PtrOfBrother;
	}
}

void updateLayers(LRTree PedigreeTree[],const int ID, const int CurrentLayer)
{
	int i = ID;

	if(MaxLayerNum < CurrentLayer)
		MaxLayerNum = CurrentLayer;
	do
	{
		PedigreeTree[i].layer = CurrentLayer;

		if(PedigreeTree[i].PtrOfLeftChild != 0)
			updateLayers(PedigreeTree,PedigreeTree[i].PtrOfLeftChild, CurrentLayer + 1);     // deep first
		else
			NoChildMemberCount[CurrentLayer]++;
		i = PedigreeTree[i].PtrOfBrother;
	}while(i != 0);

}


void printLayerNum()
{
	int i = 1;
	while(i < (MaxLayerNum))
	{
		cout<<NoChildMemberCount[i]<<" ";
		i++;
	}
	cout<<NoChildMemberCount[i]<<endl;
}

int main()
{
	int N,M;
	LRTree PedigreeTreeInit(0,0,0);
	LRTree PedigreeTree[101];
	int i;
	//while(1)
	{
		for(i = 0;i < 101;i++)
		{
			PedigreeTree[i] = PedigreeTreeInit;
			NoChildMemberCount[i] = 0;
		}
		NoChildMemberCount[i] = 0;
		MaxLayerNum = 0;
		cin>>N>>M;
		if(N == 1)
		{
			cout<<1<<endl;
		}
		else
		{
			for(i = 0;i < M;i++)
			{
				MemberInput(PedigreeTree);
			}
			updateLayers(PedigreeTree,01,1);
			printLayerNum();
		}
	}

	return 0;
}


### 关于C语言PAT乙级1004题的解法与解析 对于PAT乙级1004题,题目描述涉及处理学生的信息记录。具体来说,程序需要接收一系列的学生数据,每条数据包括学生的姓名、学号以及成绩,并最终按照特定的要求输出这些信息。 #### 题目结构分析 根据给出的内容,在该类问题中,输入的第一行为正整数\(n\)表示后续会有\(n\)组学生信息待录入;而接下来的每一行则对应一位学生具体的个人信息——依次为姓名、学号和成绩[^5]。值得注意的是,这里的姓名和学号长度均不会超过十个字符,而且所有学生的成绩都是独一无二的。 #### 编程实现要点 为了高效完成此类任务,可以考虑如下几个方面: - **存储方式的选择**:由于涉及到对学生信息的操作(如查询最高分最低分的同学),因此推荐使用数组或者链表来保存每位同学的数据。 - **排序逻辑的设计**:当面对求取最值的需求时,可以直接遍历整个列表找到最大最小值对应的索引位置,也可以先对原始数据按一定规则排序后再选取首位元素作为目标对象。 - **格式化输出控制**:最后一步是要严格按照题目规定的格式打印结果,注意各字段间的间隔符及换行等问题。 下面是一个简单的代码框架用于解决这个问题: ```c #include <stdio.h> #include <string.h> typedef struct { char name[11]; char id[11]; int score; } Student; int main() { int n, i; scanf("%d", &n); Student students[n]; for(i = 0; i < n; ++i){ scanf("%s %s %d", students[i].name, students[i].id, &(students[i].score)); } // 找到分数最高的学生 int maxIndex = 0; for(i = 1; i < n; ++i){ if(students[maxIndex].score < students[i].score) maxIndex = i; } // 找到分数最低的学生 int minIndex = 0; for(i = 1; i < n; ++i){ if(students[minIndex].score > students[i].score) minIndex = i; } printf("%s %s\n%s %s\n", students[maxIndex].name, students[maxIndex].id, students[minIndex].name, students[minIndex].id); return 0; } ``` 上述代码实现了基本的功能需求,即读入多名学生的资料并找出其中得分最高者与最低者的相关信息加以展示。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值