Fractal
Time Limit: 1000MS | Memory Limit: 30000K | |
Total Submissions: 7621 | Accepted: 3681 |
Description
A fractal is an object or quantity that displays self-similarity, in a somewhat technical sense, on all scales. The object need not exhibit exactly the same structure at all scales, but the same "type" of structures must appear on all scales.
A box fractal is defined as below :
Your task is to draw a box fractal of degree n.
A box fractal is defined as below :
- A box fractal of degree 1 is simply
X
- A box fractal of degree 2 is
X X
X
X X
- If using B(n - 1) to represent the box fractal of degree n - 1, then a box fractal of degree n is defined recursively as following
B(n - 1) B(n - 1) B(n - 1) B(n - 1) B(n - 1)
Your task is to draw a box fractal of degree n.
Input
The input consists of several test cases. Each line of the input contains a positive integer n which is no greater than 7. The last line of input is a negative integer −1 indicating the end of input.
Output
For each test case, output the box fractal using the 'X' notation. Please notice that 'X' is an uppercase letter. Print a line with only a single dash after each test case.
Sample Input
1 2 3 4 -1
Sample Output
X - X X X X X - X X X X X X X X X X X X X X X X X X X X X X X X X - X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X 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个图形中包含了第n-1个图形,第n-2个图形……第1个图形
所以当n=7时,可以包含所有图形,所以用一个3^6【边长】的二维数组存放图形就好了,然后对每个n,控制输出的大小即可
从第一个图形X开始,复制出右上角、正中心、左下角,右下角,即可得图形2,然后依次复制,得到最终的图形
用strncpy(char* , const char*,size)函数 配合 4个for循环进行复制
上代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
using namespace std;
char s[1000][1000];<span style="white-space:pre"> </span>//1000的边长,妥妥够了。。。
int pow_n(int n) //求3^x ,今天才知道,pow()里面得是浮点型。。。CE了两次。。。只能自己写一个
{
int ans=1;
for(int i=0;i<n;i++)
ans*=3;
return ans;
}
int main()
{
// freopen("2083.out","w",stdout);
int n;
for(int i=1;i<=1000;i++)
for(int j=1;j<=1000;j++)
s[i][j]=' '; //先把所有的初始化为空格
s[1][1]='X'; //第一个,其他的都能用它复制过来
for(int i=2;i<=7;i++) //输入不大于7,所以2到7,规模很小,所以不用担心超时神马的。。。
{
int temp=pow_n(i-2); //pow_n()自己写的函数,求3的(i-2)次方,这个距离下面会经常用,每次复制的行数是它,每行的个数也是它,空白的距离也是它
for(int j=1;j<=temp;j++) //第一次复制,右上角
strncpy(s[j]+2*temp+1,s[j]+1,temp); //跳开两个temp的距离,因为下标从1开始的,所以最后要+1,从s[j]+1开始,复制temp个字符
for(int j=1;j<=temp;j++) //第二次复制,正中心
strncpy(s[j+temp]+temp+1,s[j]+1,temp); //向下跳开一个temp的距离,向右跳一个temp的距离,就是正中心了,开始复制
for(int j=1;j<=temp;j++) //第三次复制,左下角
strncpy(s[j+2*temp]+1,s[j]+1,temp); //向下跳开两个temp的距离就是左下角,开始复制
for(int j=1;j<=temp;j++) //第四次复制,右下角
strncpy(s[j+2*temp]+2*temp+1,s[j]+1,temp); //向下跳开两个temp的距离,向右跳开两个temp的距离,就是右下角,开始复制
}
//至此,输入为7时的图形已经存入了s数组中,只要控制输出即可
while(scanf("%d",&n)!=EOF)
{
if(n==-1)
break;
for(int i=1;i<=pow_n(n-1);i++)<span style="white-space:pre"> </span>//控制输出规模即可
{
for(int j=1;j<=pow_n(n-1);j++)
printf("%c",s[i][j]);
printf("\n");
}
printf("-\n");<span style="white-space:pre"> </span>//别忘了输出这个。。。
}
return 0;
}
方法二:递归与分治
比上面快一丢丢~~~
直接上代码吧:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
using namespace std;
bool s[1000][1000];
int dis[10]={1,3,9,27,81,243,729}; //移动的距离
void print(int x,int y,int n) //(x,y)为右上角的那个坐标,n表示当前打印的规模
{
if(n==1)
{
s[x][y]=true;
return ;
}
int temp=dis[n-2];
print(x,y,n-1); //打印左上角
print(x,y+2*temp,n-1); //打印右上角
print(x+temp,y+temp,n-1); //打印正中心
print(x+2*temp,y,n-1); //打印左下角
print(x+2*temp,y+2*temp,n-1); //打印右下角
}
int main()
{
int n;
memset(s,false,sizeof(s)); //只要初始化一次,其他的都一样。。。
while(scanf("%d",&n)!=EOF)
{
if(n==-1)
break;
print(1,1,n);
for(int i=1;i<=dis[n-1];i++)
{
for(int j=1;j<=dis[n-1];j++)
if(s[i][j])
printf("X");
else
printf(" ");
printf("\n");
}
printf("-\n");
}
return 0;
}