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

前言

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

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

超级圣诞树(BC115) 【题解】超详细_第1张图片 

题目

描述

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

输入描述

输入圣诞树的大小 n

1 ≤  n ≤  8

输出描述

输出对应的圣诞树

难度 中等

题目链接  BC 115 超级圣诞树

示例1

输入:

1

输出:

  *
 * *
* * *
  *

说明:


示例2

输入:

2

输出:

     *
    * *
   * * *
  *     *
 * *   * *
* * * * * *
     *
     *
说明:

超级圣诞树(BC115) 【题解】超详细_第2张图片

示例3

输入:

3

输出:

           *
          * *
         * * *
        *     *
       * *   * *
      * * * * * *
     *           *
    * *         * *
   * * *       * * *
  *     *     *     *
 * *   * *   * *   * *
* * * * * * * * * * * *
           *
           *
           *

说明:


超级圣诞树(BC115) 【题解】超详细_第3张图片

 

示例4 

输入:

4

输出:

                       *
                      * *
                     * * *
                    *     *
                   * *   * *
                  * * * * * *
                 *           *
                * *         * *
               * * *       * * *
              *     *     *     *
             * *   * *   * *   * *
            * * * * * * * * * * * *
           *                       *
          * *                     * *
         * * *                   * * *
        *     *                 *     *
       * *   * *               * *   * *
      * * * * * *             * * * * * *
     *           *           *           *
    * *         * *         * *         * *
   * * *       * * *       * * *       * * *
  *     *     *     *     *     *     *     *
 * *   * *   * *   * *   * *   * *   * *   * *
* * * * * * * * * * * * * * * * * * * * * * * *
                       *
                       *
                       *
                       *

说明:


超级圣诞树(BC115) 【题解】超详细_第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,所以我们要考虑二维数组的取值范围 ,避免数组大小不够

 

首先根据图案分析 他们的一次增长的行和列的规律,

超级圣诞树(BC115) 【题解】超详细_第5张图片

分析上述 得到结论  

行数 与 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;

超级圣诞树(BC115) 【题解】超详细_第6张图片

 然后等到打印的时候,数字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];//再把左下到复制的,也复制到右下
			}
		}

 

图解

超级圣诞树(BC115) 【题解】超详细_第7张图片

 

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

超级圣诞树(BC115) 【题解】超详细_第8张图片 

 如图

超级圣诞树(BC115) 【题解】超详细_第9张图片

 这就是所要打印的图案

超级圣诞树(BC115) 【题解】超详细_第10张图片(当然必须是n>1)

 

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

 

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

再以 超级圣诞树(BC115) 【题解】超详细_第11张图片为基准,当n = 3时 ,制作左下三角,制作右下三角

超级圣诞树(BC115) 【题解】超详细_第12张图片

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

 然后把图形打印出来

	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");
	}

 

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

 超级圣诞树(BC115) 【题解】超详细_第13张图片

 

加油! 

你可能感兴趣的:(【C语言】,算法,c语言)