题解 | #超级圣诞树#
超级圣诞树
http://www.nowcoder.com/practice/470d26c9a73e4e17be8cc45cac843423
大致思路:一个大树由三个次小树组成,分别在上、左下、右下三个位置,所以递归绘制即可,具体细节标在注释里了。这个和Repeater这道题有点像。
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
void copy(vector<vector<bool>> &pic, vector<vector<bool>> orgin, int x, int y);
void draw(int depth, int x, int y, vector<vector<bool>> &pic, vector<vector<bool>> orgin);
void Print(vector<vector<bool>> pic, int lenx, int leny);
int main()
{
int n;
vector<vector<bool>> orgin;
//初始化原始小树
orgin.resize(3);
for (int i = 0; i < 3; i++) //将输入为 1 时的图形存放到数组内
for (int j = 0; j < 5; j++)
{
if ((i == 0 && j == 2) || (i == 1 && j % 2 == 1) || (i == 2 && j % 2 == 0))
orgin[i].push_back(1);
else
orgin[i].push_back(0);
}
while (cin >> n)
{
int lenx = 5 * (1 << (n - 1)) + (1 << (n - 1)) - 1;
int leny = 3 * (1 << (n - 1));
// cout << lenx << " " << leny << endl;
vector<vector<bool>> pic;
//初始化大树
pic.resize(leny);
for (int i = 0; i < leny; i++)
for (int j = 0; j < lenx; j++)
pic[i].push_back(0);
draw(n, 0, 0, pic, orgin);
Print(pic, lenx, leny); //画树叶
//画树干
for (int i = 0; i < n; i++)
{
for (int j = 0; j < lenx / 2; j++) //画空格,知道底部的中间
cout << " ";
cout << "*" << endl;
}
}
}
void copy(vector<vector<bool>> &pic, vector<vector<bool>> orgin, int x, int y)
{
//把小树拷贝到指定坐标,x和y为宽5高3的长方形的左上顶点,不是树尖
for (int i = y; i < y + 3; i++)
for (int j = x; j < x + 5; j++)
pic[i][j] = orgin[i - y][j - x];
}
void draw(int depth, int x, int y, vector<vector<bool>> &pic, vector<vector<bool>> orgin)
{
if (depth == 1)
copy(pic, orgin, x, y);
else
{
// 规律:n=depth的大树由三个n=depth-1的次小树组成
int lenx = 5 * (1 << (depth - 1)) + (1 << (depth - 1)) - 1;
int leny = 3 * (1 << (depth - 1));
draw(depth - 1, x + lenx / 4 + 1, y, pic, orgin); //上面的三角形
draw(depth - 1, x, y + leny / 2, pic, orgin); //左下的三角形
draw(depth - 1, x + lenx / 2 + 1, y + leny / 2, pic, orgin); //右下的三角形
}
}
void Print(vector<vector<bool>> pic, int lenx, int leny)
{
for (int i = 0; i < leny; i++)
{
for (int j = 0; j < lenx; j++)
{
if (pic[i][j] == 0)
cout << " ";
else
cout << "*";
}
cout << endl;
}
}