题解 | #超级圣诞树#
超级圣诞树
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; }