The Sierpinski Fractal
Time Limit: 1000MS |
|
Memory Limit: 30000K |
Total Submissions: 2684 |
|
Accepted: 1240 |
Description
Consider a regular triangular area, divide it into four equal triangles of half height and remove the one in the middle. Apply the same operation recursively to each of the three remaining triangles. If we repeated this procedure infinite times, we'd obtain something with an area of zero. The fractal that evolves this way is called the Sierpinski Triangle. Although its topological dimension is 2, its Hausdorff-Besicovitch dimension is log(3)/log(2)~1.58, a fractional value (that's why it is called a fractal). By the way, the Hausdorff-Besicovitch dimension of the Norwegian coast is approximately 1.52, its topological dimension being 1.
For this problem, you are to outline the Sierpinski Triangle up to a certain recursion depth, using just ASCII characters. Since the drawing resolution is thus fixed, you'll need to grow the picture appropriately. Draw the smallest triangle (that is not divided any further) with two slashes, to backslashes and two underscores like this:
/\
/__\
To see how to draw larger triangles, take a look at the sample output.
Input
The input contains several testcases. Each is specified by an integer n. Input is terminated by n=0. Otherwise 1<=n<=10 indicates the recursion depth.
Output
For each test case draw an outline of the Sierpinski Triangle with a side's total length of 2
n characters. Align your output to the left, that is, print the bottom leftmost slash into the first column. The output must not contain any trailing blanks. Print an empty line after each test case.
Sample Input
3
2
1
0
Sample Output
/\
/__\
/\ /\
/__\/__\
/\ /\
/__\ /__\
/\ /\ /\ /\
/__\/__\/__\/__\
/\
/__\
/\ /\
/__\/__\
/\
/__\
Hint
The Sierpinski-Triangle up to recursion depth 7
三角形分形
思路:
将整个图案考虑成一个矩形,矩形长为4*2^(size-1),宽为2^size,
然后按行枚举矩形内每一个点,判断是哪个字符并输出。
此题的关键在于如何判断大小为size图形的i行j列是哪个字符,
考虑到大小为n的图形是由3个大小为size-1的图形构成,那么
可以将size图形中的(i,j)坐标转化为size-1图形中对应的坐标,
转化关系如下:
1:
当i <2^(size-1) 并且 j >= 2^(size-1) 并且 j <3*2^(size-1)时
在size-1图形中对应的坐标为(i ,j-2^(size-1) )
2:
当 i >= 2^(size-1) 并且 j <2^size时
在size-1图形中对应的坐标为(i-2^(size-1) ,j)
3:
当 i >= 2^(size-1) 并且 j >= 2^size时
在size-1图形中对应的坐标为(i-2^(size-1) ,j-2^size)
画图举个例子:
例如计算size为3时6行9列的字符,过程如下:
1:
判断得到该坐标点在右下方的大小为2的图形中,将(6,9)
点转化为size为2的坐标系坐标(2,1)
2:
判断(2,1)点在左下方大小为1的图形中,将(2,1)点
转化为size为1的坐标系坐标(0,1)
3:
返回size为1图形的(0,1)点的字符
#include
#include
using namespace std;
#define EASY 0
int mul[13];
char map[][10] = {" /\\ " ,"/__\\"};
void get_pow()
{
int i ,r;
mul[0] = 1;
for(r = 1 ,i = 1 ; i <13 ;i ++)
{
r *= 2;
mul[i] = r;
}
}
inline
int mpow(int a ,int b)
{
return mul[b];
}
char get_out(int size ,int i, int j)
{
char r = ' ';
int m = mul[size-1];
if(size == 1)
{
return map[i][j];
}
#if 0 == EASY
//未化简版
if(i = 4*mpow(2 ,size-2)/2 && j <4*mpow(2 ,size-2)/2*3)
r = get_out(size-1 ,i ,j - 4*mpow(2 ,size-2)/2);
else if(i >= mpow(2 ,size-1) && j <4*mpow(2 ,size-2))
r = get_out(size-1 ,i - mpow(2 ,size-1) ,j );
else if(i >= mpow(2 ,size-1) && j >= 4*mpow(2 ,size-2))
r = get_out(size-1 ,i - mpow(2 ,size-1) ,j - 4*mpow(2 ,size-2));
#else
//化简版
if(i = m && j <(m<<1)+m)
r = get_out(size-1 ,i ,j - m);
else if(i >= m && j =m && j >= 2*m)
r = get_out(size-1 ,i - m ,j - 2*m);
#endif
return r;
}
int main()
{
int i ,j ,size ,k;
get_pow();
while(cin>>size && 0 != size)
{
for(i = 0 ;i