超级圣诞树(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");
	}

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

加油!

相关推荐
小安同学iter3 小时前
SQL50+Hot100系列(11.9)
算法·leetcode·职场和发展
炼金士4 小时前
基于多智能体技术的码头车辆最快行驶路径方案重构
算法·路径规划·集装箱码头
小刘max5 小时前
最长递增子序列(LIS)详解:从 dp[i] 到 O(n²) 动态规划
算法·动态规划
谢景行^顾6 小时前
数据结构知识掌握
linux·数据结构·算法
ShineWinsu6 小时前
对于数据结构:堆的超详细保姆级解析——下(堆排序以及TOP-K问题)
c语言·数据结构·c++·算法·面试·二叉树·
DuHz6 小时前
基于时频域霍夫变换的汽车雷达互干扰抑制——论文阅读
论文阅读·算法·汽车·毫米波雷达
hetao17338377 小时前
ZYZ28-NOIP模拟赛-Round4 hetao1733837的record
c++·算法
Nebula_g7 小时前
C语言应用实例:解方程(二分查找)
c语言·开发语言·学习·算法·二分查找·基础
散峰而望7 小时前
C语言刷题-编程(一)(基础)
c语言·开发语言·编辑器
少许极端8 小时前
算法奇妙屋(十)-队列+宽搜(BFS)
java·数据结构·算法·bfs·宽度优先·队列