超级圣诞树(BC115) 【题解】超详细

前言

这个题看了很久,没想出来,然后看了一些大佬的题解(可能是我的理解能力有些慢),中途有很多次放弃的想法,但是最终坚持着 ,研究明白了。

所以想结合我的想法更加具体分享一下

题目

描述

今天是圣诞节,牛牛要打印一个漂亮的圣诞树送给想象中的女朋友,请你帮助他实现梦想

输入描述

输入圣诞树的大小 n

1 ≤ n ≤ 8

输出描述

输出对应的圣诞树

难度 中等

题目链接 BC 115 超级圣诞树

示例1

输入:

复制代码
1

输出:

复制代码
  *
 * *
* * *
  *

说明:

复制代码

示例2

输入:

复制代码
2

输出:

复制代码
     *
    * *
   * * *
  *     *
 * *   * *
* * * * * *
     *
     *
说明:
复制代码

示例3

输入:

复制代码
3

输出:

复制代码
           *
          * *
         * * *
        *     *
       * *   * *
      * * * * * *
     *           *
    * *         * *
   * * *       * * *
  *     *     *     *
 * *   * *   * *   * *
* * * * * * * * * * * *
           *
           *
           *

说明:

复制代码

示例4

输入:

复制代码
4

输出:

复制代码
                       *
                      * *
                     * * *
                    *     *
                   * *   * *
                  * * * * * *
                 *           *
                * *         * *
               * * *       * * *
              *     *     *     *
             * *   * *   * *   * *
            * * * * * * * * * * * *
           *                       *
          * *                     * *
         * * *                   * * *
        *     *                 *     *
       * *   * *               * *   * *
      * * * * * *             * * * * * *
     *           *           *           *
    * *         * *         * *         * *
   * * *       * * *       * * *       * * *
  *     *     *     *     *     *     *     *
 * *   * *   * *   * *   * *   * *   * *   * *
* * * * * * * * * * * * * * * * * * * * * * * *
                       *
                       *
                       *
                       *

说明:

复制代码

解题的核心思想: 使用二维数组来进行存储图案

代码展示

cpp 复制代码
#include<stdio.h>
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<col+(col+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]

第二步 构造那个小三角 给二维数组部分初始化(先初始化一个小三角)【核心】

cpp 复制代码
int arr[400][800] = {{0,0,1,0,0},{0,1,0,1,0},{1,0,1,0,1}};

初始时 3行 5列

cpp 复制代码
int i, j = 0, k, row = 3, col = 5;

然后等到打印的时候,数字0表示 " ",数字1表示 "*"

注意这里的起初三角就是 放在数组最左上方 ,因为根据组成指定的圣诞树,所以这里为了方便先进行 分别复制左下和右下边的三角形 ,然后 再把最左上那个三角形进行 想办法移动到中间。

1.把左下角和右下角的三角形复制过去

cpp 复制代码
		//先进行复制
		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),然后再把其重新复制到中间

cpp 复制代码
		//因为最开始的三角形是靠近最左的,清空后再重新置放到左下和右下的中间
		//先清空
		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<col+(col+1)/2;k++) //这里的 /2 是为了放置于中间
			{
				arr[j][k] = arr[j + row][k-((col+1)/2)]; //左下复制到中间
			}
		}

如图

这就是所要打印的图案

(当然必须是n>1)

接着就是按照这样的思想,发现

cpp 复制代码
		//根据规律和递归思想 ,该树的变化和2次方有关系
		row *= 2;
		col = col*2 +1;//这里的加1是方便为了中间放置三角形

再以 为基准,当n = 3时 ,制作左下三角,制作右下三角

总结就是这样每一次复制下去

然后把图形打印出来

cpp 复制代码
	for (i = 0; i < row; i++)
	{//打印圣诞树
		for (j = 0; j < col; j++)
		{
			if (arr[i][j] == 0)
			{
				printf(" ");
			}
			else
			{
				printf("*");
			}
		}
		printf("\n");
	}

第三步 打印树柄

打印星号的位置就是在 列的 1/2 处打印

cpp 复制代码
	//打印树柄
	for (i = 0; i < n;i++)
	{
		for (j = 0; j < col / 2;j++)
		{
			printf(" ");
		}
		printf("*\n");
	}

最后 还是感谢网上大佬无私地分享题解,启发了我,虽然花费很久,但是收获也是很大的。

加油!

相关推荐
电院工程师7 分钟前
SM3算法Python实现(无第三方库)
开发语言·python·算法·安全·密码学
小刘同学++44 分钟前
用 OpenSSL 库实现 3DES(三重DES)加密
c++·算法·ssl
梦境虽美,却不长2 小时前
C语言 学习 宏命令(预处理) 2025年6月9日14:41:39
c语言·开发语言·学习
写写闲篇儿2 小时前
搜索二维矩阵
线性代数·算法·矩阵
时时三省2 小时前
【时时三省】(C语言基础)将外部变量的作用域扩展到其他文件
c语言
LunaGeeking2 小时前
重要的城市(图论 最短路)
c++·算法·编程·图论·最短路·floyd
刘小小_算法工程师2 小时前
「ECG信号处理——(17)基于小波熵阈值的R峰检测(与时域-频域-多尺度小波法对比)」2025年6月12日
算法·信号处理
电控极客2 小时前
电动汽车驱动模式扭矩控制设计方法
经验分享·算法·汽车·策略模式
jz_ddk2 小时前
[python] 使用python设计滤波器
开发语言·python·学习·算法
快乐肚皮3 小时前
快速排序优化技巧详解:提升性能的关键策略
java·算法·性能优化·排序算法