教授的测试
转眼之间,新学期已经过去几个月了,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;
}
&spm=1001.2101.3001.5002&articleId=6909405&d=1&t=3&u=621aead0a72c44e0b4ae0113cbff1177)
1000

被折叠的 条评论
为什么被折叠?



