Fractal(POJ-2083)

Fractal

Time Limit: 1000MS Memory Limit: 30000K
Total Submissions: 18227 Accepted: 7521

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 :

  • 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
-

题意:

分析:

思路1: 

将字符存在二维数组 map 中,然后输出该数组; 

注:

在理解递归思路之后,需要注意的就是输出问题,如果按两层循环输出二维数组,将超时,故用 cout 或 puts 直接输出一行字符串,但 puts 较快;

AC代码1: 

#include<cstdio>
#include<cmath>
#include<cstring>
char map[731][731];
void print(int n,int x,int y){
	int size;
	if(n == 1)	map[x][y] = 'X';
	else if(n > 1){
		size = pow(3.0,n-2);
		print(n-1, x, y); //左上角   
		print(n-1, x, y+2*size); //右上角       
		print(n-1, x+size, y+size); //中间 
		print(n-1, x+2*size, y);    //左下角 
		print(n-1, x+2*size, y+2*size); //右下角 
	}
}
int main(void){
	int n, size;
	while(scanf("%d", &n) && n!=-1){
		memset(map, ' ', sizeof(map));
		size = pow(3.0, n-1);
		print(n, 0, 0); 
        /*从 (0, 0) 开始递归而不是 (1, 1),因为 puts 输出的是一整行字符串,
          从 (1, 1) 开始的话,每一行的第一个字符都是空格,与题目要输出的结果不同*/
		for(int i = 0; i < size; i++){
			map[i][size] = '\0';
			puts(map[i]);
			//也可以用 cout 输出,但 puts 较快; 
		}
		printf("-\n");
	}
	return 0;
}

 思路2:

 这道题在乎的是全局性,而且还有重叠,题中说 n<=7,那么我们可以直接把 n=7 的情况处理出来,之后直接输出图形的左上角。也用二维数组进行存储。

AC代码2: 

#include<cstdio>
#include<cstring>
int bc[10];
char map[731][731];
void print(int n,int x,int y){
	if(n == 1)	map[x][y]='X';
	else if(n > 1){
		print(n-1, x, y); //左上方 
		print(n-1, x, y+2*bc[n-1]); //右上方 
		print(n-1, x+bc[n-1], y+bc[n-1]); //中间 
		print(n-1, x+2*bc[n-1], y); //左下方 
		print(n-1, x+2*bc[n-1], y+2*bc[n-1]); //右下方 
	}
}
int main(){
	bc[1] = 1;
	for(int i = 2; i <= 7; i++) 
		bc[i] = bc[i-1]*3;
	memset(map, ' ', sizeof(map));
	print(7, 1, 1);
	int n;
	while(scanf("%d",&n) && n != -1){
		for(int i = 1; i <= bc[n]; i++){
			map[i][bc[n]+1] = '\0';
			puts(map[i]+1);
			map[i][bc[n]+1] = ' ';
			/*由于只调用了一次 print 函数,但有多组测试数据,
			所以得把换行改回空格,否则如果下一个测试数据比上
			一个测试数据大时,右上角会缺失。 */ 
		}	
		printf("-\n");
	}
	return 0;
}

思路3:

用三维数组 f[ i ][ j ][ k ] 存储图形,i 表示盒方形图的度,j 表示行,k 表示列,如果点 [ j ][ k ] 为 X,记为真,否则记为假;

由于 n<=7,直接把 n=7 的情况处理出来,随后输出左上角。

AC代码3:

#include <cstdio>
int n, l[10];
bool f[731][731][731];
int main() {
	l[1] = 1;
	f[1][1][1] = 1;
	// i:i度的盒方形图		j:行 		k:列 
	for (int i = 2; i <= 7; ++i) {
		int len = l[i - 1];
		for (int j = 1; j <= len; ++j)
			for (int k = 1; k <= len; ++k) {
				f[i][j][k] = f[i - 1][j][k]; //左上角 
				f[i][j][2 * len + k] = f[i - 1][j][k];  //右上角 
				f[i][len + j][len + k] = f[i - 1][j][k]; //中间 
				f[i][2 * len + j][k] = f[i - 1][j][k]; //左下角 
				f[i][2 * len + j][2 * len + k] = f[i - 1][j][k]; //右下角 
			}
		l[i] = 3 * l[i - 1];
	}
	while (scanf("%d", &n) && n!=-1) {
		int len = l[n];
		for (int i = 1; i <= len; ++i) {
			for (int j = 1; j <= len; ++j)
				putchar(f[n][i][j] ? 'X' : ' ');
			putchar('\n');
		}
		puts("-");
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值