前言
这个题看了很久,没想出来,然后看了一些大佬的题解(可能是我的理解能力有些慢),中途有很多次放弃的想法,但是最终坚持着 ,研究明白了。
所以想结合我的想法更加具体分享一下
题目
描述
今天是圣诞节,牛牛要打印一个漂亮的圣诞树送给想象中的女朋友,请你帮助他实现梦想
输入描述
输入圣诞树的大小 n
1 ≤ n ≤ 8
输出描述
输出对应的圣诞树
难度 中等
题目链接 BC 115 超级圣诞树
输入:
1
输出:
* * * * * * *
说明:
输入:
2
输出:
* * * * * * * * * * * * * * * * * * * * 说明:
输入:
3
输出:
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
说明:
输入:
4
输出:
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
说明:
解题的核心思想: 使用二维数组来进行存储图案
代码展示
#include
int main()
{
//使用二维数组存储圣诞树
/*
* 首先根据规律计算出 二维数组行和列的上限
* //行的规律是 pow(2,(n-1))*3+n 当n == 8时 row = 392
* //列的规律是 pow(2,n)*3 - 1 当n == 8时 col = 769
* //所以进而确定行和列的取值范围
*/
int n = 0;
scanf("%d",&n);
int arr[400][800] = {{0,0,1,0,0},{0,1,0,1,0},{1,0,1,0,1}};
int i, j = 0, k, row = 3, col = 5;
for (i = 2; i <= n; i++)//n>=2时才使用二维数组进行排(方便依次的递增)
{
//先进行复制
for (j = row; j < row * 2; j++)
{
for (k = 0; k < col;k++)
{
arr[j][k] = arr[j - row][k];//复制为左下方的三角形
arr[j][k + col + 1] = arr[j][k];//再把左下到复制的,也复制到右下
}
}
//因为最开始的三角形是靠近最左的,清空后再重新置放到左下和右下的中间
//先清空
for (j = 0; j < row;j++)
{
for (k = 0; k < col;k++)
{
arr[j][k] = 0;
}
}
//放到中央(这时需要我们把之前已经复制好的左下三角形复制到中央(当然右下也可以,左下比较方便))
for (j = 0; j < row;j++)
{
for (k = (col+1)/2;k
因为这里的思想是使用二维数组来进行存储图案,然后发现随着输入数字的增大,圣诞树也是有一定规律的增大,这里有点像递归的思想。发现图案是由 一个个3行5列的三角组成的
接下来就进行一步一步来分析:
第一步 因为圣诞树的大小为 1- 8,所以我们要考虑二维数组的取值范围 ,避免数组大小不够
首先根据图案分析 他们的一次增长的行和列的规律,
分析上述 得到结论
这里我们取 n == 8 行数为 392,列数为 767
所以为了避免越界我们取 二维数组的范围 arr[400][800]
第二步 构造那个小三角 给二维数组部分初始化(先初始化一个小三角)【核心】
int arr[400][800] = {{0,0,1,0,0},{0,1,0,1,0},{1,0,1,0,1}};
初始时 3行 5列
int i, j = 0, k, row = 3, col = 5;
然后等到打印的时候,数字0表示 " ",数字1表示 ”*“
注意这里的起初三角就是 放在数组最左上方 ,因为根据组成指定的圣诞树,所以这里为了方便先进行 分别复制左下和右下边的三角形 ,然后 再把最左上那个三角形进行 想办法移动到中间。
1.把左下角和右下角的三角形复制过去
//先进行复制
for (j = row; j < row * 2; j++)
{
for (k = 0; k < col;k++)
{
arr[j][k] = arr[j - row][k];//复制为左下方的三角形
arr[j][k + col + 1] = arr[j][k];//再把左下到复制的,也复制到右下
}
}
图解
2.把最左上的三角先清空(置0),然后再把其重新复制到中间
//因为最开始的三角形是靠近最左的,清空后再重新置放到左下和右下的中间
//先清空
for (j = 0; j < row;j++)
{
for (k = 0; k < col;k++)
{
arr[j][k] = 0;
}
}
//放到中央(这时需要我们把之前已经复制好的左下三角形复制到中央(当然右下也可以,左下比较方便))
for (j = 0; j < row;j++)
{
for (k = (col+1)/2;k
如图
这就是所要打印的图案
接着就是按照这样的思想,发现
//根据规律和递归思想 ,该树的变化和2次方有关系
row *= 2;
col = col*2 +1;//这里的加1是方便为了中间放置三角形
总结就是这样每一次复制下去
然后把图形打印出来
for (i = 0; i < row; i++)
{//打印圣诞树
for (j = 0; j < col; j++)
{
if (arr[i][j] == 0)
{
printf(" ");
}
else
{
printf("*");
}
}
printf("\n");
}
第三步 打印树柄
打印星号的位置就是在 列的 1/2 处打印
//打印树柄
for (i = 0; i < n;i++)
{
for (j = 0; j < col / 2;j++)
{
printf(" ");
}
printf("*\n");
}
最后 还是感谢网上大佬无私地分享题解,启发了我,虽然花费很久,但是收获也是很大的。
加油!