[HDU] 1100 Trees Made to Order catalan数的应用
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1100
方法:
首先根据输入的n判断出树里有多少个点m,然后设点数小于等于m的数的形态个数为x,则远问题转换成求n个点组成的树中排名第n-x的树的形态
设buildTree(count,order)为建立count的点组成的树中排名order的树。
核心就在该函数里。
先设i是左子树的个数,0<=i<=count-1,而右子树是j=cout-1-i,
依次考查每一个i,考查的时候又依次考查i个点对应的k个形态,直到发现一个形态的排名达到目标排名order。通过模拟可以计算得出左子树有多少个点lcount,形态排名lorder,右子树多少个点rcount,形态排名rorder。然后递归调用buildTree(lcount,lorder)和buildTree(rcount,rorder)来分别构造左右子树。
代码:
#include <iostream>
#include <queue>
#include <iomanip>
using namespace std;
int catalan[18]={1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, 2674440, 9694845, 35357670, 129644790};
int catalanSum[18];
struct Node
{
Node* left;
Node* right;
};
Node* createTree(int count,int order)
{
if(count==0)
return NULL;
Node* re = (Node*)malloc(sizeof(Node));
re->left=NULL;
re->right=NULL;
if(count==1)
return re;
int sonCount = count-1;
int t_sortNo=0;
for(int i=0;i<=sonCount;i++)
{
for(int j=1;j<=catalan[i];j++)
{
if(t_sortNo+catalan[sonCount-i]>=order)
{
re->left = createTree(i,j);
re->right = createTree(sonCount-i,order-t_sortNo);
return re;
}
else
t_sortNo+=catalan[sonCount-i];
}
}
}
void outputTree(Node* root)
{
if(root->left!=NULL)
{
cout<<"(";
outputTree(root->left);
cout<<")";
}
cout<<"X";
if(root->right!=NULL)
{
cout<<"(";
outputTree(root->right);
cout<<")";
}
}
int main()
{
int n;
catalanSum[0]=1;
for(int i=1;i<18;i++)
catalanSum[i]=catalanSum[i-1]+catalan[i];
while(scanf("%d",&n)&& n!=0)
{
n++;
int i=0;
while(catalanSum[i]<n&&i<18)//i<18很重要的条件
i++;
n-=catalanSum[i-1];
outputTree(createTree(i,n));
cout<<endl;
}
return 0;
}
感想:细心
浙公网安备 33010602011771号