一. 题目
原题 BC115 超级圣诞树(下面截图看不清的话可直接点链接看原题~)
描述
今天是圣诞节,牛牛要打印一个漂亮的圣诞树送给想象中的女朋友,请你帮助他实现梦想。
输入描述:
输入圣诞树的大小 nn
1≤n≤81≤n≤8
输出描述:
输出对应的圣诞树
二. 思路分析
主要分为三部分:
根据对应的n,在数组对应位置中(即最顶部那个位置)存入最基础的情形(如下)
* //其位置为tree[0][3*2^(n-1)-1];其他的都可由这个顶部坐标推出;
* *
* * *
主体部分:递归思想的实现
每一次复制,都是将原来的图形复制给左下角右下角各一个;
每一次复制后,通过改变range的范围,将复制后得到的两个和原来的那个看作一个新的整体,再复制给下一个,是非常巧妙的设计,成果实现了递归思想。
打印部分(较简单):
打印圣诞树主体部分:通过找规律,确定圣诞树的长宽;
打印圣诞树树干部分:每行先打空格,再打*。
三. 代码实现
#include <stdio.h>
#include <math.h>
int main()
{
char tree[400][800] = { 0 };//创建二维数组,以承载整个圣诞树的图案;
int n, copy, i, j;//copy代表复制的次数,i代表行,j代表列;
scanf("%d", &n);
int top_y = 3 * pow(2, n - 1) - 1;//圣诞树顶点所在的列数
//(明确指出,是为了让最基础的图形,即圣诞树的前三层能在不同n时都放对在对应的位置上)
//将n=1时的最基础的那个形状对应的图案,放入圣诞树数的第一层;
//有助于后续复制的进行(递归思想,最简单的情形)
tree[0][top_y] = '*';
tree[1][top_y - 1] = '*';
tree[1][top_y + 1] = '*';
tree[2][top_y - 2] = '*';
tree[2][top_y] = '*';
tree[2][top_y + 2] = '*';
for (copy = 1; copy < n; copy++)//代表复制的次数;
{
int range = 3 * pow(2, copy - 1);//很巧妙的设计——通过改变range,即复制的范围来实现递归——
//不断将复制得到的两个与原来的那个构成一个新的整体,再复制给下一层的两个;
//复制出右下角和左下角的两个图案:
for (i = 0; i < range; i++)
{
for (j = top_y - range + 1; j < top_y + range; j++)
{
tree[i + range][j - range] = tree[i][j];//tree[i + range][j - range]是左下角那个待复制的位置
tree[i + range][j + range] = tree[i][j];//tree[i + range][j - range]是右下角那个待复制的位置
}
}
}
//打印圣诞树主体部分(不难,只要用表达式正确表达圣诞树长宽<-找规律总结得到,即可):
for (i = 0; i < 3 * pow(2, n - 1); i++)
{
for (j = 0; j < 3 * pow(2, n); j++)
{
if ('*' == tree[i][j])
{
printf("*");
}
else
{
printf(" ");
}
}
printf("\n");
}
//打印树干的部分(简单):
for (int i = 0; i < n; i++)
{
for (int j = 0; j < top_y; j++)
{
printf(" ");
}
printf("*\n");
}
return 0;
}