分形,具有以非整数维形式充填空间的形态特征。通常被定义为“一个粗糙或零碎的几何形状,可以分成数个部分,且每一部分都(至少近似地)是整体缩小后的形状”,即具有自相似的性质。
一个盒状分形定义如下:
度为1的盒分形为:
X
度为2的盒分形为:
X X
X
X X
依次类推,如果B(n-1)表示n-1度的盒分形,则n度的盒分形递归定义如下:
B(n - 1) B(n - 1)
B(n - 1)
B(n - 1) B(n - 1)
请画出度为n的盒分形的图形
输入格式:
输入一系列度,每行给出一个不大于7的正整数。输入的最后一行以-1表示输入结束
输出格式:
对于每个用例,输出用'X'标记的盒状分形。在每个测试用例后输出包含一个短划线“-”的一行。
输入样例:
1
2
3
4
-1
输出样例:
注意:每行的空格请输出完整。
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
-
源码
#include <bits/stdc++.h>
using namespace std;
#define SIZE 730
char paper[SIZE][SIZE];
void generatePaper(int x0, int y0, int dimension)
{
if (dimension == 1)
{
paper[x0][y0] = 'X';
}
else
{
int subScale = pow(3, dimension - 2);
generatePaper(x0, y0, dimension - 1);
generatePaper(x0 + 2 * subScale, y0, dimension - 1);
generatePaper(x0, y0 + 2 * subScale, dimension - 1);
generatePaper(x0 + 2 * subScale, y0 + 2 * subScale, dimension - 1);
generatePaper(x0 + subScale, y0 + subScale, dimension - 1);
}
}
int main()
{
for (int i = 0; i < SIZE; ++i)
{
for (int j = 0; j < SIZE; ++j)
{
paper[i][j] = ' ';
}
}
generatePaper(0, 0, 7);
int dimension;
cin >> dimension;
while (dimension != -1)
{
for (int i = 0; i < pow(3, dimension - 1); ++i)
{
for (int j = 0; j < pow(3, dimension - 1); ++j)
{
cout << paper[i][j];
}
cout << endl;
}
cout << "-" << endl;
cin >> dimension;
}
return 0;
}
思路
读完题目,很容易想到要用递归分治,根据输入输出的要求,总结用动态规划。
原因:动态规划和递归分治的区别其实就在于前者把每一个小问题的结果都进行了保存,避免了利用递归分治方法解决问题时重复解决一个小问题的情况出现。本题采用动态规划方法就是因为题目说了输入会是一系列度,假如说是每次读入一个度都进行递归分治,那其实会增加程序的运行时间,不如提前把度为7的图案预先存储起来,以后在读取一系列度时,根据度来进行输出就好了,这样就避免了每次都要重新生成新的图案的情况,节约了时间。
利用二维数据进行图案的实现
原因: 设想一下,假如这是一道小学数学题,老师要求我们将图案画在作业纸上,那我们其实很容易就能画出来,而且可以有许多不同的画法(从左上角开始画/从右上角开始画/从中间开始往外扩张的画/等等)。但是计算机不会从纸张上面的任意一个位置画,它只会从左到右,一行一行,从上到下的开始画,所以这就是难点所在了。利用二维数组其实就是把这个二维数组想象成一张纸,因为二维数组的随机存取特性,这就帮助我们实现了在纸上的任意一个位置开始画,随意的画。
分治——找规律
原因: 接着说回分治,要想画一个n度的图案,其实就是画5个n-1度的图案。那么问题就由如何画一个n度的图案转变为如何画一个n-1度的图案和这5个n-1度的图案应该从哪画起的问题了。第一个问题好解决,画一个n-1度的图案,其实就是画5个n-2度的图案......第二个问题就是找规律,我们从左至右,从上至下,以此对五个图案进行从0至4的标号,我们默认每个图案都是从左上角开始画起的,所以就用每个图案的左上角来代表每个图案的位置了。0图案和1图案的高度一样,他们横向距离相差2个n-1度图案的规模......
递归函数
函数的作用是画出一个图案,图案的左上角在(x0,y0),规模为dimension。
由此得知该函数的参数表有三个参数,分别为x0,y0和dimension。
其中当dimension==1时,直接画出'X';
当dimension!=1时,那么就画出五个newDimension=dimension-1的图案,其位置由上述规律总结得出。