FZU 1064 教授的测试(Catalan数的应用)

本文介绍了一种使用卡特兰数解决二叉树排列问题的方法,并通过递归算法实现了根据树的排名确定其具体结构的过程。文中还详细解释了如何通过卡特兰数快速定位二叉树的节点数量及其子树的排列。

题目链接>>FZU 1064 教授的测试


解法:卡特兰数的应用。用递归直接输出。根据这个树排名,来确定左子树的节点个数和排名,以及右子树的节点个数和排名。


关于卡特兰数的应用总结,可以参考这几篇文章
http://blog.youkuaiyun.com/dacc123/article/details/50922138
http://blog.youkuaiyun.com/myue5/article/details/7984061
https://wenku.baidu.com/view/c2f253d226fff705cc170ad6.html


看完上述文章后是不是理解为啥要用 Catalan 数来做了吗?
因为节数为 i 的二叉树最多有Catalani


定义 ctl 数组为 Catalan 数前17项
(为什么是17项,因为

i=116Catalani=48760366<108

i=117Catalani=178405156>108


定义sum数组为ctl数组的前缀和( sum 里面ctl[0]不算进去,因为没有排名为 0 的树)
如果
n(sumi,sumi+1]
那么我们可以判断排名为 n 的二叉树有i+1个节点
这棵树在有 i+1 个节点的树中排名为 nsumi
然后我们可以来递归搜索了,因为对于一棵树只要知道他子树的节点数和其排名就可以求出这棵树了

#include<cstdio>
int sum[18]={1,1,3,8,22,64,196,625,2055,6917,23713,82499,290511,1033411,3707851,13402696,48760366,178405156};
int ctl[18]={1,1,2,5,14,42,132,429,1430,4862,16796,58786,208012,742900,2674440,9694845,35357670,129644790};
void dfs(int x,int rank){
    if(x==1){putchar('X');return;}//边界条件 
    int i=x,tot=0;//i表示右子树有几个点 
    while(tot<rank){i--;tot+=ctl[i]*ctl[x-i-1];}//左子树有x-i-1个节点时,右子树有i个节点时的总方案数
    rank=rank-(tot-ctl[i]*ctl[x-i-1])-1;//减去前面那一堆算出当前树在 左子树有x-i-1个节点时,右子树有i个节点 的树中的排名 
    if(x-i-1>0)putchar('('),dfs(x-i-1,rank/ctl[i]+1),putchar(')');//在左子树中,排名每增加1 右子树要增加ctl[i]次 
    putchar('X');//令左子树在左子树的rank中为ranky,右子树为rankx,所以就有(ranky-1)*ctl[i]+rankx=rank(ranky∈[1,ctl[x-i-1]],rankx∈[1,ctl[x]]) 
    if(i>0)putchar('('),dfs(i,rank%ctl[i]+1),putchar(')');//所以rankx=rank%ctl[i] ranky=rank/ctl[i]+1 但是由于rankx可能等于ctl[i]导致结果出错 
}//所以不妨做个小处理(ranky-1)*ctl[i]+(rankx-1)=rank-1 这样就可以避免上述情况了,此时 rankx=rank%ctl[i]+1 ranky=rank/ctl[i]+1
int main(){
    int i,n;
    while(scanf("%d",&n),n!=0){
        for(i=0;i<=17;i++)if(sum[i]<n&&n<=sum[i+1])break;
        dfs(i+1,n-sum[i]);puts("");
    }
return 0;
}

其实 Catalan 数列很神奇,但是在组合数学中还有许许多多的神奇数列,有兴趣的可以去了解一下,这里就不做赘述了。

谢谢观看!

内容概要:本文档是一份关于交换路由配置的学习笔记,系统地介绍了网络设备的远程管理、交换机与路由器的核心配置技术。内容涵盖Telnet、SSH、Console三种远程控制方式的配置方法;详细讲解了VLAN划分原理及Access、Trunk、Hybrid端口的工作机制,以及端口镜像、端口汇聚、端口隔离等交换技术;深入解析了STP、MSTP、RSTP生成树协议的作用与配置步骤;在路由部分,涵盖了IP地址配置、DHCP服务部署(接口池与全局池)、NAT转换(静态与动态)、静态路由、RIP与OSPF动态路由协议的配置,并介绍了策略路由和ACL访问控制列表的应用;最后简要说明了华为防火墙的安全区域划分与基本安全策略配置。; 适合人群:具备一定网络基础知识,从事网络工程、运维或相关技术岗位1-3年的技术人员,以及准备参加HCIA/CCNA等认证考试的学习者。; 使用场景及目标:①掌握企业网络中常见的交换与路由配置技能,提升实际操作能力;②理解VLAN、STP、OSPF、NAT、ACL等核心技术原理并能独立完成中小型网络搭建与调试;③通过命令示例熟悉华为设备CLI配置逻辑,为项目实施和故障排查提供参考。; 阅读建议:此笔记以实用配置为主,建议结合模拟器(如eNSP或Packet Tracer)动手实践每一条命令,对照拓扑理解据流向,重点关注VLAN间通信、路由选择机制、安全策略控制等关键环节,并注意不同设备型号间的命令差异。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值