题解 | #超级圣诞树#

超级圣诞树

https://www.nowcoder.com/practice/470d26c9a73e4e17be8cc45cac843423

#include <stdio.h>
#include <math.h>
//树身和树干部分分开,树身是一个复制的思想,有几层就复制几遍,树干单独输出,用二维数组输出,初始小圣诞树单独建立 
//行的特征是3*2^(n-1),列的特征是3*2^n-1,400*800即够用
//观察发现,每次均是将单棵小树在其左下方和右下方复制一次,可以认为每次均是将已有节点复制到两个新的位置,且两个位置对称,并有逻辑位置关系
int main() {
    int a=0;
    scanf("%d", &a);//a用来存多大的树
    int row = 3 * (int)pow((double)2, (double)(a - 1));//记录输出多少行
    int column = 3 * (int)pow((double)2, (double)a) - 1;//记录输出多少列
    char tree[400][800] = { 0 };//画布
    for (int i = 0; i < 400; i++) {
        for (int j = 0; j < 800; j++) {
            tree[i][j] = 32;//即空格
        }
    }//这个for循环对画布初始化,均是空格,初始化也可以用memset
    int middle = row;//middle定位树的顶点
    tree[0][middle-1] = '*'; tree[1][middle - 2] = '*'; tree[1][middle ] = '*';
    tree[2][middle - 3]= '*'; tree[2][middle + 1] = '*'; tree[2][middle-1] = '*';
    //初始化最顶端小树;
    //下面开始复制
    int b = a - 1;//递归次数
    int c = 3;//初始一个变量方便循环,初始行
    int r = middle+2;//初始列,右定位
    int l = middle - 2;//初始列,左定位
    int time = 1;
    while (b>0) {
        for (int i = 0; i < c; i++) {
            for (int j = l-1; j < r; j++) {
                if ('*' == tree[i][j]) {//该点是*时,将其复制到两个对称
                    tree[i + c][j - c] = '*';
                    tree[i + c][j + c] = '*';
                }
            }
        }
        c *= 2;
        l = l - 3 * time;
        r = r + 3 * time;
        time *= 2;//这里面time变量其实多余,可以精简下,懒得改了
        b--;
    }

    for (int i = 0; i < row; i++) {//打印tree
        for (int j = 0; j < column; j++) {
            printf("%c", tree[i][j]);
        }
        printf("\n");
    }
    for (int i = 1; i <= a; i++) {//打印最底下的*;
        b =middle-1;//这里懒得定义新变量了,随便拿了一个前面的用
        while (b > 0) {
            printf(" ");
            b--;
        }
        printf("*\n");
    }
    return 0;
}

全部评论

相关推荐

点赞 评论 收藏
转发
1 1 评论
分享
牛客网
牛客企业服务