分形(递归&&坐标变换)

笑着哭i 提交于 2020-02-20 02:16:44

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

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

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

一级盒子分形:

   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-1级图形作为n级图形的左上角,n-1级图形的每个坐标分别加上四个偏移量得到n级图形的其余四个分量

完整代码:

//1、非递归(循环利用坐标变换):
#include <iostream>
#include <cstring>
#include <cmath>
using namespace std;
const int maxn=3010;
int n;
int ch[maxn][maxn];

void init()
{
    ch[1][1]=1;
    for(int k=2;k<=8;k++){
        int p=pow(3,k-2);
        for(int i=1;i<=p;i++){
            for(int j=1;j<=p;j++){
                ch[i+2*p][j]=ch[i][j+2*p]=ch[i+p][j+p]=ch[i+2*p][j+2*p]=ch[i][j];//把n-1级图形作为n级图形的左上角,这个图形的每个坐标分别加上四个偏移量得到其余四个分量
            }
        }
    }
}

void output()
{
    int N=pow(3,n-1);
    for(int i=1;i<=N;i++){
        for(int j=1;j<=N;j++){
            if(ch[i][j]) cout<<"X";
            else cout<<" ";
        }
        cout<<endl;
    }
    cout<<"-"<<endl;
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    init();
    while(cin>>n&&n!=-1){
        output();
    }
    return 0;
}


//2、非递归(+去掉末尾空格(虽然这里不用!QAQ))
#include <iostream>
#include <cstring>
#include <cmath>
using namespace std;
const int maxn=3000;
int n;
char ch[maxn][maxn],ss[maxn][maxn];

void init()
{
    ch[1][1]='X';
    for(int k=2;k<=8;k++){
        int p=pow(3,k-2);
        for(int i=1;i<=p;i++){
            for(int j=1;j<=p;j++){
                ch[i+2*p][j]=ch[i][j+2*p]=ch[i+p][j+p]=ch[i+2*p][j+2*p]=ch[i][j];
            }
        }
    }
}

void output()
{
    int N=pow(3,n-1);
    memcpy(ss,ch,sizeof ch);
    for(int i=N;i>=1;i--){
        for(int j=N;j>=1;j--){
            if(ss[i][j]=='X') break;
            ss[i][j]='Y';//把末尾空格都变成‘Y’
        }
    }
    for(int i=1;i<=N;i++){
        for(int j=1;j<=N;j++){
            if(ss[i][j]=='Y') break;
            if(ss[i][j]) cout<<ss[i][j];
            else cout<<" ";//注意这里字符为空,不代表是空格,所以要特判
        }
        cout<<endl;
    }
    cout<<"-"<<endl;
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    init();
    while(cin>>n&&n!=-1){
        output();
    }
    return 0;
}


//3、递归(利用坐标变换):
#include <iostream>
#include <cmath>
using namespace std;
const int maxn=1010;
char ch[maxn][maxn];
int n;

void dfs(int x)
{
    if(x==1){
        ch[1][1]='X';
        return;
    }
    dfs(x-1);
    int dx[5]={2,0,1,2},dy[5]={0,2,1,2};//四个位置x和y的偏移量
    int len=pow(3,x-2);
    for(int i=0;i<4;i++){
        for(int j=1;j<=len;j++){
            for(int k=1;k<=len;k++){
                ch[j+dx[i]*len][k+dy[i]*len]=ch[j][k];
            }
        }
    }
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    dfs(7);
    while(cin>>n&&n!=-1){
        int len=pow(3,n-1);
        for(int i=1;i<=len;i++){
            for(int j=1;j<=len;j++){
                if(ch[i][j]) cout<<ch[i][j];
                else cout<<" ";
            }
            cout<<endl;
        }
        cout<<"-"<<endl;
    }
    return 0;
}

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!