POJ 1095 Trees Made to Order(计数问题)

Trees Made to Order

Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 6882   Accepted: 3940

Description

We can number binary trees using the following scheme:

The empty tree is numbered 0.

The single-node tree is numbered 1.

All binary trees having m nodes have numbers less than all those having m+1 nodes.

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.

The first 10 binary trees and tree number 20 in this sequence are shown below:

Your job for this problem is to output a binary tree when given its order number.

Input

Input consists of multiple problem instances. Each instance consists of a single integer n, where 1 <= n <= 500,000,000. A value of n = 0 terminates input. (Note that this means you will never have to output the empty tree.)

Output

For each problem instance, you should output one line containing the tree corresponding to the order number for that instance. To print out the tree, use the following scheme:

A tree with no children should be output as X.

A tree with left and right subtrees L and R should be output as (L‘)X(R‘), where L‘ and R‘ are the representations of L and R.

If L is empty, just output X(R‘).

If R is empty, just output (L‘)X.

Sample Input

1
20
31117532
0

Sample Output

X
((X)X(X))X
(X(X(((X(X))X(X))X(X))))X(((X((X)X((X)X)))X)X)

Source

East Central North America 2001

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<set>
#include<map>

#define L(x) (x<<1)
#define R(x) (x<<1|1)
#define MID(x,y) ((x+y)>>1)

#define eps 1e-8
typedef __int64 ll;

#define fre(i,a,b)  for(i = a; i < b; i++)
#define free(i,b,a) for(i = b; i >= a;i--)
#define mem(t, v)   memset ((t) , v, sizeof(t))
#define ssf(n)      scanf("%s", n)
#define sf(n)       scanf("%d", &n)
#define sff(a,b)    scanf("%d %d", &a, &b)
#define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)
#define pf          printf
#define bug         pf("Hi\n")

using namespace std;

#define INF 0x3f3f3f3f
#define N 20

int dp[N];

void inint()
{
	int i,j;
	dp[0]=dp[1]=1;
	for(i=2;i<N;i++)
	{
		fre(j,0,i)
		  dp[i]+=dp[j]*dp[i-1-j];  //i个节点的情况有列举左边放j,因为根节点需要一个,那么右边i-1-j
	}

}

void dfs(int n,int k)    //n个节点,第k大
{
	if(n==1)    //开始是k==1,一直错
	{
		pf("X");
		return ;
	}

	int i=0;
    for(i=0;;i++)
		if(dp[i]*dp[n-i-1]>=k) break;  //左边有dp[i]种情况,右边有dp[n-i-1],因为有一个点当根节点
	 else  k-=dp[i]*dp[n-i-1];

    if(i)       //左边有节点
	{
		pf("(");
		dfs(i,(k-1)/dp[n-i-1]+1);
		pf(")");
	}
	pf("X");
	if(n-i-1)    //右边有节点
	{
		pf("(");
		dfs(n-1-i,(k-1)%dp[n-1-i]+1);
		pf(")");
	}
}
int main()
{
	int i,j,n;
	inint();
	while(sf(n),n)
	{
		for(i=1;;i++)
		  if(dp[i]>=n) break; //已经锁定i个节点是满足条件的
		 else n-=dp[i];
		dfs(i,n);
      pf("\n");
	}
    return 0;
}
时间: 2024-10-17 14:12:43

POJ 1095 Trees Made to Order(计数问题)的相关文章

POJ 1095 Trees Made to Order

题目大意: 按照题意将数用二叉树的形式表示出来.将二叉树按照要求形式输出. 解题思路: 由于有图示,可以轻易看出这个顺序跟卡特兰数列有关.且对于任意一个树的任意子树来说,右子树相当于分针,左子树相当于秒针.也就是说当右子树要变换到下一种状态时,左子树要将它所能变换的状态全变换完才可以. 下面是代码: #include <set> #include <map> #include <queue> #include <math.h> #include <ve

POJ 1095 Trees Made to Order 最详细的解题思路

题目来源:Trees Made to Order 题目大意:根据下面的规则给一棵二叉树编号: 规则1:如果二叉树为空,则编号为0: 规则2:如果二叉树只有一个节点,则编号为1: 规则3:所有含有m个节点的二叉树的编号小于所有含有m+1个节点的二叉树的编号: 规则4:如果一棵含有m个节点的二叉树(左子树为L,右子树为R)的编号为n,要想其它含有m个节点的二叉树的编号如果大于n,则需要满足两个条件中的任意一个:1.左子树的编号大于L的编号:2.左子树的编号等于L的编号,但是右子树的编号大于R的编号.

POJ 2665 Trees

Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10075   Accepted: 6622 Description The road off the east gate of Peking University used to be decorated with a lot of trees. However, because of the construction of a subway, a lot of them

poj 1095 题解(卡特兰数+递归

题目 题意:给出一个二叉树的编号,问形态. 编号依据 1:如果二叉树为空,则编号为0: 2:如果二叉树只有一个节点,则编号为1: 3:所有含有m个节点的二叉树的编号小于所有含有m+1个节点的二叉树的编号: 4:如果一棵含有m个节点的二叉树(左子树为L,右子树为R)的编号为n,要想其它含有m个节点的二叉树的编号如果大于n,则需要满足两个条件中的任意一个:1.左子树的编号大于L的左子树的编号等于L的编号,但是右子树的编号大于R的编号.(大概就是先将右子树的个数填满将变幻完后再将右子树的点向左子树转移

HDOJ-1100 Trees made to order

一.题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1100二.题目分析 对二叉树的所有形态顺序编号,编号规则是:节点数越多的编号越大:节点数相等,左子树节点数越多的越大:节点数相等,左子树节点数也相等,则依此规则比较右子树. 现给定一个正整数,依题目要求输出对应编号的二叉树形态. 三.求解思路 由题目输出格式要求,很直观地联想到使用深度优先搜索dfs,以当前二叉树对应的编号为条件,依次递归输出左子树和右子树. 1 int main(void) 2

POJ 2665 Trees(水题)

[题意简述]:就是有一段路上有和长度加一的值相等的数目,现在要在这条路上修路,所以要砍掉一些树,问剩下了多少树. [分析]:很简单,注意一的处理就好. //216K 79Ms #include<iostream> using namespace std; int main() { int len,n,s,e; while(cin>>len>>n) { int sum = 0; if(len == 0&&n == 0) break; for(int i =

ACM训练方案-POJ题目分类

ACM训练方案-POJ题目分类 博客分类: 算法 ACM online Judge 中国: 浙江大学(ZJU):http://acm.zju.edu.cn/ 北京大学(PKU):http://acm.pku.edu.cn/JudgeOnline/ 杭州电子科技大学(HDU):http://acm.hdu.edu.cn/ 中国科技大学(USTC):http://acm.ustc.edu.cn/ 北京航天航空大学(BUAA)http://acm.buaa.edu.cn/oj/index.php 南京

转载:poj题目分类(侵删)

转载:from: POJ:http://blog.csdn.net/qq_28236309/article/details/47818407 按照ac的代码长度分类(主要参考最短代码和自己写的代码) 短代码:0.01K–0.50K:中短代码:0.51K–1.00K:中等代码量:1.01K–2.00K:长代码:2.01K以上. 短:1147.1163.1922.2211.2215.2229.2232.2234.2242.2245.2262.2301.2309.2313.2334.2346.2348

poj题库分类

初期:一.基本算法:     (1)枚举. (poj1753,poj2965)     (2)贪心(poj1328,poj2109,poj2586)     (3)递归和分治法.     (4)递推.     (5)构造法.(poj3295)     (6)模拟法.(poj1068,poj2632,poj1573,poj2993,poj2996)二.图算法:     (1)图的深度优先遍历和广度优先遍历.     (2)最短路径算法(dijkstra,bellman-ford,floyd,hea