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;
}