递归打印图形

分形
分形,具有以非整数维形式充填空间的形态特征。

通常被定义为“一个粗糙或零碎的几何形状,可以分成数个部分,且每一部分都(至少近似地)是整体缩小后的形状”,即具有自相似的性质。

现在,定义“盒子分形”如下:

一级盒子分形:

X
二级盒子分形:

1
2
3
X X
X
X X

如果用B(n - 1)代表第n-1级盒子分形,那么第n级盒子分形即为:

1
2
3
4
5
B(n - 1)        B(n - 1)

B(n - 1)

B(n - 1) B(n - 1)

你的任务是绘制一个n级的盒子分形。

输入格式

输入包含几个测试用例。

输入的每一行包含一个不大于7的正整数n,代表要输出的盒子分形的等级。

输入的最后一行为-1,代表输入结束。

输出格式

对于每个测试用例,使用“X”符号输出对应等级的盒子分形。

请注意’X’是一个大写字母。

每个测试用例后输出一个独立一行的短划线。

输入样例:

1
2
3
4
5
1
2
3
4
-1

输出样例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
X
-
X X
X
X X
-
X X X X
X X
X X X X
X X
X
X X
X X X X
X X
X X X X
-
X X X X X X X X
X X X X
X X X X X X X X
X X X X
X X
X X X X
X X X X X X X X
X X X X
X X X X X X X X
X X X X
X X
X X X X
X X
X
X X
X X X X
X X
X X X X
X X X X X X X X
X X X X
X X X X X X X X
X X X X
X X
X X X X
X X X X X X X X
X X X X
X X X X X X X X
-

递归 + 递推优化(减少递归的分支数,减小时间复杂度)
对于n级来说,只用画 5 个n - 1级,递归终止条件为 n == 1 true时,然后进行回溯,画剩下的4个(由第n级的 n - 1级复制过来)然后往上继续回溯

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1005;
bool a[N][N]; //由于只有画与不画两种状态(要画的只有一种图形),
int qsm(int a, int b) //快速幂,用来计算len的长度
{
int res = 1;
while(b)
{
if(b & 1) res *= a;
a = a * a;
b >>= 1;
}
return res;
}

void dfs(int n) //n级分形的规划
{
if(n == 1) //1级直接画
{
a[0][0] = true; //先画左上角
return ;
}
dfs(n - 1); //进行dfs,靠回溯来完善整个图形
int len = qsm(3, n - 2); //长度为n级的n - 1 级(n级由 5 个 n - 1级组成) ,那么表示就会表示为 3 ^ (n - 2)
int px[4] = {0, 1, 2, 2}, py[4] = {2, 1, 0, 2}; //n级里的 其它4个n - 1级的开始坐标(左上角)
for(int i = 0; i < 4; i ++ ) //4种情况
for(int j = 0; j < len; j ++ ) //i 表示4个 n - 1级的图形,j, k为横纵坐标(为了进行复制)
for(int k = 0; k < len; k ++ ) //4种情况,以len为基础
a[j + px[i] * len][k + py[i] * len] |= a[j][k]; //进行"等位"(加上中心偏移量)复制
}
int main()
{
dfs(7); //预先算出答案,空间换时间
int n;
while(cin >> n && n != -1)
{
int len = qsm(3, n - 1); //每级的长度为3 ^ n - 1
for(int i = 0; i < len; i ++ )
{
for(int j = 0; j < len; j ++ )
if(a[i][j]) cout << 'X'; //1状态输出'X', 否则为' '
else cout << ' ';
puts(""); //记得换行
}
cout << '-' << endl;
}
return 0;
}

0%