题目背景
自从到了南蛮之地,孔明不仅把孟获收拾的服服帖帖,而且还发现了不少少数民族的智慧,他发现少数民族的图腾往往有着一种分形的效果,在得到了酋长的传授后,孔明掌握了不少绘图技术,但唯独不会画他们的图腾,于是他找上了你的爷爷的爷爷的爷爷的爷爷……帮忙,作为一个好孙子的孙子的孙子的孙子……你能做到吗?
题目描述
给定一个正整数 n n n,参考输出样例,输出图形。
输入格式
每个数据输入一个正整数 n n n,表示图腾的大小(此大小非彼大小)。
输出格式
这个大小的图腾。
样例
样例输入1
1
样例输出1
/\
/__\
样例输入2
2
样例输出2
/\
/__\
/\ /\
/__\/__\
样例输入3
3
样例输出3
/\
/__\
/\ /\
/__\/__\
/\ /\
/__\ /__\
/\ /\ /\ /\
/__\/__\/__\/__\
说明/提示
数据保证, 1 ≤ n ≤ 10 1 \le n \le 10 1≤n≤10。
思路
首先,我们观察样例输出的长,宽。
当
n
=
1
n = 1
n=1 时,长
4
4
4格,宽
2
2
2格。
当
n
=
2
n = 2
n=2 时,长
8
8
8格,宽
4
4
4格。
当
n
=
3
n = 3
n=3 时,长
16
16
16格,宽
8
8
8格。
通过上述的数据,我们可以发现,长
2
n
+
1
2 ^ {n + 1}
2n+1格,宽
2
n
2 ^ n
2n格。
因为
1
≤
n
≤
10
1 \le n \le 10
1≤n≤10,所以我们至少要开一个
2048
×
1024
2048 \times1024
2048×1024 的数组存储答案。
其次,我们来观察图形。
图形包含许多的三角形。
我们发现,最小的三角形边长为
2
2
2,每一个三角形的变成是比其小的三角形的边长
×
2
\times 2
×2,且每一个三角形都包含
3
3
3 个比其小的三角形,位置在最上方,左下方和右下方。
由此,我们可以考虑递归。
从最大的三角形(边长为
2
n
2 ^ n
2n)开始递归,每次画出三角形,并找出各边的中点向下一层递归。如果边长等于
1
1
1,返回。
具体细节详见代码。
注意事项
- 答案数组最初要初始化为‘ ’(空格),否则系统默认为 ASCLL码 为 0 0 0 的字符。虽然也能输出空格,但会被系统判错(不可见字符);
- 注意你的数组下标是从 0 0 0 开始的还是 1 1 1 开始的;
- 字符’‘需要转义(即’\');
- 数组不要开成 1024 × 1024 1024 \times 1024 1024×1024。
代码
#include<bits/stdc++.h>
using namespace std;
int n;
char mp[4000][4000];
void dfs(int x, int y, int p){
int tx1, tx2;//左边中点坐标
int ty1, ty2;//右边中点坐标
if(p == 1){//边长为1
return;
}
int u = p / 2;//下一层边长
//画左边的边
int px = x, py = y;
for(int i = 1; i <= p; ++ i){
mp[px][py] = '/';
px ++;
py --;
if(i == u){
tx1 = px;
ty1 = py;
}
}
int t = py + 1;
//画右边的边
px = x, py = y + 1;
for(int i = 1; i <= p; ++ i){
mp[px][py] = '\';//转义
px ++;
py ++;
if(i == u){
tx2 = px;
ty2 = py - 1;
}
}
-- px;
-- py;
//下面的边
for(int i = t + 1; i < py; ++ i){
mp[px][i] = '_';
}
//下一层
dfs(x, y, u);
dfs(tx1, ty1, u);
dfs(tx2, ty2, u);
}
int main(){
scanf("%d", &n);
//计算最大三角形的边长(同时也是宽和长的一半)
//注意,pow函数可能会因精度误差而导致计算错误
int s = 1;
for(int i = 1; i <= n; ++ i){
s *= 2;
}
//初始化,可以用memset(mp, ' ', sizeof(mp))
for(int i = 1; i <= s; ++ i){
int t = s * 2;
for(int j = 1; j <= t; ++ j){
mp[i][j] = ' ';
}
}
dfs(1, s, s);
for(int i = 1; i <= s; ++ i){
int t = s * 2;
for(int j = 1; j <= t; ++ j){
putchar(mp[i][j]);
}
putchar('\n');
}
return 0;
}