题解 | #超级圣诞树#
超级圣诞树
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;
}
查看3道真题和解析
