前言
这个题看了很久,没想出来,然后看了一些大佬的题解(可能是我的理解能力有些慢),中途有很多次放弃的想法,但是最终坚持着 ,研究明白了。
所以想结合我的想法更加具体分享一下
题目
描述
今天是圣诞节,牛牛要打印一个漂亮的圣诞树送给想象中的女朋友,请你帮助他实现梦想
输入描述
输入圣诞树的大小 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
1)/2;k++) //这里的 /2 是为了放置于中间 - {
- arr[j][k] = arr[j + row][k-((col+1)/2)]; //左下复制到中间
- }
- }
-
- //根据规律和递归思想 ,该树的变化和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");
- }
-
- //打印树柄
- for (i = 0; i < n;i++)
- {
- for (j = 0; j < col / 2;j++)
- {
- printf(" ");
- }
- printf("*\n");
- }
- return 0;
- }
因为这里的思想是使用二维数组来进行存储图案,然后发现随着输入数字的增大,圣诞树也是有一定规律的增大,这里有点像递归的思想。发现图案是由 一个个3行5列的三角组成的
接下来就进行一步一步来分析:
第一步 因为圣诞树的大小为 1- 8,所以我们要考虑二维数组的取值范围 ,避免数组大小不够
首先根据图案分析 他们的一次增长的行和列的规律,
分析上述 得到结论
行数 与 n 的关系
列数与 n 的关系
这里我们取 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
1)/2;k++) //这里的 /2 是为了放置于中间 - {
- arr[j][k] = arr[j + row][k-((col+1)/2)]; //左下复制到中间
- }
- }
如图
这就是所要打印的图案
(当然必须是n>1)
接着就是按照这样的思想,发现
- //根据规律和递归思想 ,该树的变化和2次方有关系
- row *= 2;
- col = col*2 +1;//这里的加1是方便为了中间放置三角形
再以 为基准,当n = 3时 ,制作左下三角,制作右下三角
总结就是这样每一次复制下去
然后把图形打印出来
- 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");
- }
最后 还是感谢网上大佬无私地分享题解,启发了我,虽然花费很久,但是收获也是很大的。
加油!