[递归]Vicsek Fractal

来源:互联网 发布:ubuntu 修复win7引导 编辑:程序博客网 时间:2024/06/06 07:52

题目描述

Vicsek分形是一种美丽的正方形分形图案。












一阶的Vicsek分形是一个正方形:
#

二阶的Vicsek分形是会在一阶的基础上扩展:
# . #
. # .
# . #

同样的,三阶的Vicsek分形是在二阶的基础上扩展得到的.

现在给你一个整数n,输出n阶的Vicsek分形

输入

第一行是一个整数K,表示样例的个数。 每行输入一个整数n(1≤n≤8),表示要输出n阶的Vicsek分形。

输出

输出n阶的Vicsek fractal,用'.'表示空白,用'#'表示有颜色的部分。
为了美观,我们在每两个字符之间有一个空格,行尾没有空格

样例输入

3123

样例输出

## . #. # .# . ## . # . . . # . #. # .   . . .  . # .# . # . . . # . #. . .  # . # . . .. . .  . # . . . .. .  . # . # . . .# . # . . . # . #. # . . . . . # .# . # . . . # . #



队友大半夜丢给我的一道题。

第一想法当然是递归,先确定整个区域的规模,对每块区域涂上相应的颜色,一直到递归最后无法再涂色为止。

关键在于用mid和length来定位 ,使用这两个参数就比较好控制每一块区域。

把初始的颜色先用memset涂满,然后再根据规模一点点消除比较好。

难度不是很大,这题目主要还是靠强大的编码能力才能写完。

我没有晚上做题的习惯,大半夜的根本想不清楚,早上起来刷牙洗脸的时候就突然明白怎么写了。

有时候这也算是灵光一现吧 0_0 。。


#include<cmath>#include <iostream>#include<cstring>#include<cstdio>using namespace std;const int MAXN = 8000;bool G[MAXN][MAXN];int k,n;int length;void myclear(int x1,int y1,int x2,int y2){    for(int i = x1;i<=x2;i++)        for(int j = y1; j <= y2;j++)            G[i][j] = false;}void Reverse(int mid1,int mid2,int len)//确定了中间的位置和需要翻转的长度就可以{    //printf("递归:mid1 = %d, mid 2 = %d, length = %d\n",mid1,mid2,len);    if (len ==1) return ;    len = len / 3;    int up_x1 = mid1,up_y1 = mid2 - len;  //上面一块的中点    int down_x1=mid1,down_y1=mid2 + len;    int left_x1=mid1-len,left_y1 = mid2 ;    int right_x1=mid1+len,right_y1=mid2 ;    myclear(up_x1-len/2,up_y1-len/2,up_x1+len/2,up_y1+len/2);    myclear(down_x1-len/2,down_y1-len/2,down_x1+len/2,down_y1+len/2);    myclear(left_x1-len/2,left_y1-len/2,left_x1+len/2,left_y1+len/2);    myclear(right_x1-len/2,right_y1-len/2,right_x1+len/2,right_y1+len/2);    Reverse(mid1-len,mid2-len,len); //左上角    Reverse(mid1+len,mid2-len,len); //右上角    Reverse(mid1-len,mid2+len,len); //左下角    Reverse(mid1+len,mid2+len,len); //右下角    Reverse(mid1,mid2,len);    return ;}void output(){  //  printf("output:\n");    int i,j;    for(i = 1; i <= length; i++)    {        for(j = 1; j < length; j++)        {            if (G[i][j]) printf("# ");            else printf(". ");        }        if (G[i][j]) printf("#");            else printf(".");        printf("\n");    }    return ;}int main(){    cin>>k;    memset(G,true,sizeof(G));    while(k--)    {        scanf("%d",&n);        length = pow(3,n-1); //共有这么多行        int middle = length / 2 + 1;        Reverse(middle,middle,length); //x1=middle,x2=middle,length为当前的矩阵规模        output();    }    return 0;}




队友大半夜丢给我的一道题。


0 0
原创粉丝点击