POJ 1095 Trees Made to Order

二叉树编号解析
本文介绍了一种基于二叉树的编号方法,并提供了一个ACM竞赛题目的解决方案。通过递归算法,实现了根据输入数字生成对应的二叉树中序遍历表达式。此方法对于理解和实现二叉树的应用具有一定参考价值。
Run IDUserProblemResultMemoryTimeLanguageCode LengthSubmit Time
7614586kingpro1095Accepted172K0MSC++771B2010-09-14 05:44:37

 

#include<stdio.h>
#define MAXN 19
int num[MAXN]={1,1}, snum[MAXN]={1,1}, n;
void GetMum(int n){ for(int i=0; i<n && (num[n]+=num[i]*num[n-1-i]) || (snum[n]=snum[n-1]+num[n],false); i++); }
void SplitNum(int offset, int l)
{
	for(int cnt=0, i=0, offsetall=0, ni=0; 
		i<l && (cnt+=num[i]*num[l-1-i], cnt<offset) || 
		(ni=l-1-i, offsetall=offset-cnt+num[i]*num[ni]-1, 
		i!=0 && (printf("("), SplitNum(offsetall/num[ni]+1, i), printf(")")), 
		printf("X"), 
		ni!=0 && (printf("("), SplitNum(offsetall%num[ni]+1, ni),printf(")")),
		false); 
	i++);
}
int main()
{
	for(int i=2; i<MAXN && (GetMum(i), true); i++);
	while(scanf("%d", &n), n!=0) 
		for(int i=1; i<MAXN && (snum[i]<n) || (SplitNum(n-snum[i-1], i), printf("\n"), false); i++);
	return 0;
}

 

这道题在POJ上AC率很高...主要是这道题,对错与否实在是太容易看出来了,过了测试用例基本就对了,但是Submit数量才5000不到,不是很难,但是题意蛮难理解的,特别是那句“Any binary tree having m nodes with left and right subtrees L and R is numbered n such that all trees having m nodes numbered > n have either Left subtrees numbered higher than L, or A left subtree = L and a right subtree numbered higher than R.”,这么长,完全晕掉。。。

题意大概是:用一棵二叉树表示数字;节点多的二叉树表示的数字总比节点少的二叉树表示的数字大;一个父节点上的左右子节点,右节点总比左节点小。

给定一个数,输出对应二叉树的中序遍历表达式。

分析:一棵树有m个节点,那么他可能表示的数字的数量为:F(m)=Σ[i=0, m-1] F(i)*F(m-1-i),题目中给的数1 <= n <= 500,000,000,预计算 m最大为19。

解决方法:递归;给定一个数字n,先确定二叉树的节点数量m,进而分裂,确定左子树和右子树的节点数量i j和对应的值(实际使用偏移量),m=i+j+1。

值得一做的题。

转载于:https://www.cnblogs.com/Kingpro/archive/2010/09/14/POJ_1095_Trees_Made_to_Order.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值