超级圣诞树

该博客介绍了一个用C语言实现的算法,通过动态规划的方法,根据输入的大小n生成不同级别的圣诞树图案。程序通过构建二维字符数组,逐步构建每一层的圣诞树,并利用对称性填充剩余部分,最终输出完整的圣诞树。

描述

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

输入描述:

输入圣诞树的大小 nn

1≤n≤81≤n≤8

输出描述:

输出对应的圣诞树

示例1

输入:

1

复制输出:

  *
 * *
* * *
  *

示例2

输入:

2

复制输出:

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

示例3

输入:

3

输出:

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

示例4

输入:

4

输出:

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

由题目给出的示例可以看出,每个圣诞树都是由三部分组成的,中部、左下和右下。并且从示例可以看出来,每个圣诞树的三个部分均是前一级的圣诞树,所以整个圣诞树就可以采用动态规划的思想,从低级圣诞树慢慢还原到要求的圣诞树。

#include<stdio.h>
#include<math.h>
int main()
{
    char arrbefore[392][768] = { 0 };//这个数组用来存放当前状态的上一级状态
    char arrnow[392][768] = { 0 };//这个数组用来存放圣诞树目前的状态
    for (int i = 0; i < 392; i++) {//先将arrnow数组里的元素都初始化为' '
        for (int j = 0; j < 768; j++) {
            arrnow[i][j] = ' ';
        }
    }
    int n = 0;
    scanf("%d", &n);
    int q = 0;
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 5; j++) {
            if (j == 2 && i == 2){
                arrbefore[i][j] = '*';
            }
            else if (j == 2 - i) {
                arrbefore[i][j] = '*';
            }
            else if (j == 2 + i)
                arrbefore[i][j] = '*';
            else
                arrbefore[i][j] = ' ';
            q = j + (3 * pow(2, n - 1) - 3);
            arrnow[i][q] = arrbefore[i][j];
        }
    }//将arrnow和arrbefore都初始化为n=1的状态
    int k = 2;
    int t = 0;
    int p = 0;
    while (k <= n) {//k表示当前要实现的圣诞树的状态
        for (int i = 0; i < 3 * pow(2, k - 2); i++) {
            for (int j = 0; j < (3 * pow(2, k - 1) - 1); j++) {
                //下标遍历整个arrbefore数组
                p = i + 3 * pow(2, k - 2);
                //arrnow的横坐标从p开始,二级圣诞树需要从3开始,3级从6开始,依次类推
                q = j + (3 * pow(2, n - 1) - 3 * pow(2, k - 1));
                //arrnow的纵坐标从q开始
                arrnow[p][q] = arrbefore[i][j];//将arrbefore赋给arrnow
                t =( 3 * ((int)pow(2, n))) - 2 - q;
                if (arrnow[p][q] == '*')//圣诞树是对称的,所以满足对称条件就赋成'*'
                    arrnow[p][t] = '*';
            }
        }//经过这个循环就生成了k级圣诞树
        for (int i = 0; i < 3 * pow(2, k - 1); i++) {
            for (int j = 0; j < (3 * pow(2, k) - 1); j++) {
                int q = j + (3 * pow(2, n - 1) - 3 * pow(2, k - 1));
                arrbefore[i][j] = arrnow[i][q];
            }
        }//将k级圣诞树赋给arrbefore,以便生成k+1级圣诞树
        k++;//圣诞树级别+1
    }
    for (int i = 3 * pow(2, n - 1); i < 3 * pow(2, n - 1) + n; i++) {
        arrnow[i][3 * (int)pow(2, n - 1) - 1] = '*';
    }//画出树干
    for (int i = 0; i < (3 * pow(2, n - 1) + n); i++) {
        for (int j = 0; j < (3 * pow(2, n) - 1); j++) {
            printf("%c", arrnow[i][j]);
        }
        printf("\n");
    }//将有图案的地方全部打印出来
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值