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

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

加油!

相关推荐
Amor风信子10 分钟前
【力扣】2376. 统计特殊整数
算法·leetcode·职场和发展
极客小张10 分钟前
基于正点原子Linux开发板的智能监控与家电控制系统设计:深度解析Video4Linux和TCP/IP技术栈
linux·运维·c++·物联网·网络协议·tcp/ip·算法
JustCouvrir1 小时前
代码随想录算法训练营Day5
算法
只对您心动1 小时前
【C高级】有关shell脚本的一些练习
linux·c语言·shell·脚本
周哈里窗的编程2 小时前
CSP-CCF★201912-2回收站选址★
c++·算法·图论
SpongeG3 小时前
数据结构第三周做题总结_链表
数据结构·算法·链表
everyStudy3 小时前
前端五种排序
前端·算法·排序算法
小珑也要变强3 小时前
队列基础概念
c语言·开发语言·数据结构·物联网
little redcap5 小时前
第十九次CCF计算机软件能力认证-乔乔和牛牛逛超市
数据结构·c++·算法
muyierfly6 小时前
34.贪心算法1
算法·贪心算法