分形的递归输出

题干:

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

一个盒状分形定义如下: 度为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
-

 解答:

       分析:

              首先,这题需要先考虑怎么个输出法。计算机不像我们人那么灵活,我们人可以从左往右写,甚至写着写着可以从上往下,或者到纸上的任意一个位置,天马行空,而计算机只能老老实实的从左往右来,遇到换行才会往下,回车才会到一行的开头。回到此题,一行一行的输出肯定是有解法的,但对于我们人来说就没那么直观了。所以我们可以先建一个二维表,先将完事的内容存在这个数组中,再全部输出

                解决了如何输出都问题,我们就可以以我们人的方式来“写”这个题了。给你一直笔一张纸,你怎么写? 我的话,必然是从最小的开始,画一个一阶的‘X’,再画一个二阶的‘X’,慢慢变大。然后,我就在画的过程中发现了,一个大‘X’可以分成5个小部分,每个小部分都是上一阶的小‘X’。这就有意思了xdm,那我岂不是可以一直CtrlC+CtrlV了,最后堆成一个巨大‘X’。

                套娃是吧,套娃就递归嘛。递归是吧,递归就是每一步都结果就是由上一步来的。我们来看最后成型的超级超级巨大巨大的‘X',它照样也是由 5个小一丢丢的‘X’构成的:

(图以 n = 3为例)

                我们以大‘X’的左下角作为原点,这个大‘X’分成两5块,在这个坐标系下,每一小块的左下角(这个点当成是确认位置都基准点吧)的坐标都可以确认,对应的每一个小块的位置也都确认了。我们创造一个递归函数: void box(int n, int x, int y) ,在这里面,五个小老弟间隔设为m,易得m = 3^(n - 2),那这五个小老弟的位置也就定了(坐标标在图中),代入递归方程就是

        box(n - 1, x, y);

        box(n - 1, x, y + 2 * m);

        box(n - 1, x + m, y + m);

        box(n - 1, x + 2 * m, y);

        box(n - 1, x + 2 * m, y + 2 * m);

至此,五个小老弟的内容也出来了。

                什么?这难道就结束了?五个小老弟里的内容是啥你还没说!NONONO,你只要拿着放大镜去看其中一个小老弟,你就会发现它里面,也有五个小小老弟,跟他爹一个样,而这五个小小弟的位置怎么定,也是一样的。这样一直下去,直到最后的n=1为止,只要输出一个小小的‘X’就可以了。

        代码:

#include<bits/stdc++.h>
using namespace std;

const int Max = 1000;
char a[Max][Max];


void box(int n, int x, int y)
{
    if (n == 1){
        a[x][y] = 'X';

    }

    else  {

        //按照图来看
        int m = pow(3, (n - 2));

        box(n - 1, x, y);
        box(n - 1, x, y + 2 * m);
        box(n - 1, x + m, y + m);
        box(n - 1, x + 2 * m, y);
        box(n - 1, x + 2 * m, y + 2 * m);



    }  


}

int main() 
{

    int n;
    cin >> n;

    int wide;  //x的宽度
    int i, j;


    while (n != -1){

        wide = pow(3, (n - 1));

        //初始化
        for (i = 0; i < wide; i ++){
            for (j = 0; j < wide; j ++)
                a[i][j] = ' ';
            a[i][j] = '\0';
        }


        box(n, 0, 0);

        //输出
        for (i = 0; i < wide; i ++){
            cout << a[i] << endl;
        }

        cout << '-' <<endl;


        cin >> n;
    }
    

system("pause"); 
return 0;
}

 

          总结: 

            (强行升华一下吧)其实我自己也很怕递归,因为这个思路和我们平时的解法差别挺大,经常要倒着来想问题。虽然每次知道解法之后都挺恍然大悟的,但重新遇到新的题目又不知道如何下手了。(捂脸,还是多练吧)能递归的题目应该都有共同的特点,就是重复相同的步骤(废话),我想关键就是如何在不同的地方找到相同的地方吧。(好谜语人)

也是第一次写文章,难免有很多漏洞和疏忽的地方,麻烦各位大佬能不吝赐教,指出问题,万分感谢!

                  

 

                      

  • 12
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值