分形,具有以非整数维形式充填空间的形态特征。
通常被定义为“一个粗糙或零碎的几何形状,可以分成数个部分,且每一部分都(至少近似地)是整体缩小后的形状”,即具有自相似的性质。
现在,定义“盒子分形”如下:
一级盒子分形:
X
二级盒子分形:
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 的正整数 n,代表要输出的盒子分形的等级。
输入的最后一行为 −1,代表输入结束。
输出格式
对于每个测试用例,使用 X
符号输出对应等级的盒子分形。
请注意 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
-
思路:
找规律:
递归找规律,我们可以发现对于每个盒子都是正方形,边长都一样;
对于第n级的盒子分型,其边长为3^(n-1),例如2级盒子边长为3,3级盒子边长为9;
对于第n级盒子,总是由n-1级盒子复制到其他四个地方的;
n-1级盒子在左上角,n级盒子需要其复制到右上角,中间,左下角,右下角;
(画的有点丑,见谅)
解法:
用一个二维数组表示整个7级盒子,如果某个位置该放'X',就将其值置为1,否则为0;
先进行一次性预处理,求出7级盒子的样子,再根据输入的数值,输出对应大小的数组;
我们可以用len_n表示第n级盒子的边长,len_n_1表示第n-1级盒子的边长;
则我们可以发现,n级盒子右上角距离n-1级盒子的距离为2倍len_n_1,
等于将n-1级盒子向右平移2倍len_n_1的距离;
中间的部分等于n-1级盒子向下平移len_n_1,再向右平移len_n_1的距离;
左下角的部分等于n-1级盒子向下平移2倍len_n_1的距离;
右下角的部分等于n-1级盒子向右平移2倍len_n_1,向下平移2倍len_n_1的距离;
由此,递归的关系式就非常简单了,我们可以像一般的深搜一样,用两个一维数组表示行和列的变化(单位是len_n_1);
然后根据变化前的状态确定变化后的状态;(由于是复制过来的,所以变化前后状态一样);
最后根据输入的数字,输出对应边长大小的矩阵;
#include<iostream>
using namespace std;
const int N=1e3;
int B[N][N];
void dfs(int n){
if(n==1) {//第n级盒子只有一个'X';
B[0][0]=1;
return;
}
dfs(n-1);
int len_n_1=1;//表示n-1级盒子边长;
for(int i=1;i<=n-2;++i)
len_n_1*=3;
int dx[4]={0,1,2,2,},dy[5]={2,1,0,2};//表示行和列的变化,单位为len_n_1;
for(int i=0;i<4;++i)
for(int j=0;j<len_n_1;++j)
for(int k=0;k<len_n_1;++k)
B[dx[i]*len_n_1+j][dy[i]*len_n_1+k]=B[j][k];//将变化前的值复制给变化后的值;
return;
}
int main()
{
dfs(7);
int n;
while(cin>>n&&n!=-1){
int len_n=1;//len_n表示n级盒子边长;
for(int i=1;i<=n-1;++i)
len_n*=3;//边长=3^(n-1);
for(int i=0;i<len_n;++i){//根据输入的数值大小,输出对应边长大小的数组;
for(int j=0;j<len_n;++j)
if(B[i][j]==1) cout<<'X';//某一位值为1表示该输出'X',否则输出空格;
else cout<<' ';
cout<<endl;
}
cout<<'-'<<endl;
}
}
题目提交地址:提交地址