第三题:教授的测试(NOIP2009测试试题12.08)

 

 教授的测试

转眼之间,新学期已经过去几个月了,F大学计算机系的W教授决定对他的学生进行一次测试。为了测试学生对树结构的认识,同时也检验他们的编程能力,教授把测试的内容定为:要求学生们编程按编号顺序打印出节点个数不少于m的所有二叉树。

  二叉树编号规则如下:

  仅有一个元素的树编号为1。

  当满足以下条件之一时,定义二叉树a的编号比b大:

    1. a的节点数比b多。

    2. 若a的节点数与b相等,且a的左子树编号比b的左子树大。

    3. a的节点数和左子树编号都和b相等,且a的右子树编号比b的右子树大。

  二叉树的元素用大写X表示。

  例如:

 

   

  打印二叉树的格式为:

  ( 左子树 ){若左子树为空,则省略} X{根} ( 右子树 ){若右子树为空,则省略}

  例如在上图中,编号为2 的树可表示为:X(X);

         编号为3 的树可表示为:(X)X;

         编号为5 的树可表示为:X((X)X);

  当然当m较大时,检验答案对错的工作也是很繁重的,所以教授只打算对其中的若干个编号的二叉树进行抽查,他想麻烦你在测试开始前把标准答案先准备好(教授的测试卷会事先交给你)。

【输入】:

输入文件为教授的测试卷,至少1行,至多10行,每行一个数N(1<=N<=10^8),即要抽查的二叉树的编号,以零结束。

 

【输出】:

输出文件是你求出的标准答案,对每一个编号输出其对应的二叉树,每个二叉树占一行,零不用输出。

样例输入(tree.in): 样例输出(tree.out):

2                  X(X)

5                  X((X)X)

0

/******************************************************************************************************
 ** Copyright (C) 2011.07.01-2013.07.01
 ** Author: famousDT <13730828587@163.com>
 ** Edit date: 2011-10-21
******************************************************************************************************/
#include <stdio.h>
#include <stdlib.h>//abs,atof(string to float),atoi,atol,atoll
#include <math.h>//atan,acos,asin,atan2(a,b)(a/b atan),ceil,floor,cos,exp(x)(e^x),fabs,log(for E),log10
#include <vector>
#include <queue>
#include <map>
#include <time.h>
#include <set>
#include <list>
#include <stack> 
#include <string>
#include <iostream>
#include <assert.h>
#include <string.h>//memcpy(to,from,count
#include <ctype.h>//character process:isalpha,isdigit,islower,tolower,isblank,iscntrl,isprll
#include <algorithm>
using namespace std;

typedef long long ll;

#define MY_PI acos(-1)
#define MY_MAX(a, b) ((a) > (b) ? (a) : (b))
#define MY_MIN(a, b) ((a) < (b) ? (a) : (b))
#define MY_MALLOC(n, type) ((type *)malloc((n) * sizeof(type)))
#define MY_ABS(a) (((a) >= 0) ? (a) : (-(a)))
#define MY_INT_MAX 0x7fffffff

/*==========================================================*\
| 
\*==========================================================*/
char s0[] = "X";
char s1[] = "X(X)";
char s2[] = "(X)X";
int y[17] = {1,1,2,5,14,42,132,429,1430,4862,16796,58786,208012,742900,2674440,9694845,35357670};
int yy[16] = {1,3,8,22,64,196,625,2055,6917,23713,82499,290511,1033411,3707851,13402696,48760366};
int fun(int a, int b)
{
	if (a == 1) return 1;
	return yy[a - 2] + b;
}
char * process(int n)
{
	if (n == 1) return s0;
	else if (n == 2) return s1;
	else if (n == 3) return s2;
	else {
		int i;
		for (i = 15; i >= 0; --i) {
			if (yy[i] < n)
				break;
		}
		int x = n - yy[i];
		int index = i + 2;
		int ax = 0;
		int ay = index - 1;
		int sum = y[ax] * y[ay];
		while (x > sum) {
			x -= sum;
			ax++;
			ay--;
			sum = y[ax] * y[ay];
		}
		int xx, yy;
		xx = 0;
		yy = 0;
		for (xx = 1; ; ++xx) {
			if (x <= y[ay])
				break;
			else x -= y[ay];
		}
		yy = x;
		if (ax == 0) {
			char *s;
			s = (char *)malloc(sizeof(char) * 10000);
			strcpy(s, "X(");
			strcat(s, process(fun(ay, yy)));
			strcat(s, ")");
			return s;
		} else if (ay == 0) {
			char *s;
			s = (char *)malloc(sizeof(char) * 10000);
			strcpy(s, "(");
			strcat(s, process(fun(ax, xx)));
			strcat(s, ")X");
			return s;
		} else {
			char *s;
			s = (char *)malloc(sizeof(char) * 10000);
			strcpy(s, "(");
			strcat(s, process(fun(ax, xx)));
			strcat(s, ")X(");
			strcat(s, process(fun(ay, yy)));
			strcat(s, ")");
			return s;
		}
	}
}
int main()
{
	FILE *in,*out;
    in = fopen("tree.in","rt");
    out = fopen("tree.out","wt"); 
	int n;
	while (fscanf(in, "%d", &n) == 1, n) {
		fprintf(out, "%s\n", process(n));
	}
	fclose(in);
    fclose(out);
    return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值