18931 分形
时间限制:1000MS 代码长度限制:10KB
提交次数:0 通过次数:0
题型: 编程题 语言: G++;GCC;VC;JAVA
Description
分形,具有以非整数维形式充填空间的形态特征。
通常被定义为“一个粗糙或零碎的几何形状,可以分成数个部分,且每一部分都(至少近似地)是整体缩小后的形状”,即具有自相似的性质。
现在,定义“盒子分形”如下:
一级盒子分形:
X
二级盒子分形:
如果用B(n - 1)代表第n-1级盒子分形,那么第n级盒子分形即为:
你的任务是绘制一个n级的盒子分形。
输入格式
输入一个不大于6的正整数n,代表要输出的盒子分形的等级。
输出格式
使用“X”符号输出对应等级的盒子分形。
输入样例
4
输出样例
解题思路
递归
找规律
此题可用递归解决,递归的思想可查看下图:
第一次递归
此时 n = 4
第二次递归
此时 n = 3
第三次递归
此时 n = 2
第四次递归
此时 n = 1,结束递归
因此我们可以不断地往左上角、右上角、中心、左下角、右下角进行递归(即五次)
那我们如何在第一、第二次递归等等,确定我要找的位置在哪里呢?
我们可以用草稿纸帮助我们计算
- 第一次递归,右上角距离左上角为18个单位
- 第二次递归,右上角距离左上角为6个单位
- 第三次递归,右上角距离左上角为2个单位
这些数字有什么特点呢
- 18 = 3 ^ 3 - 3 ^ 2(n = 4)
- 6 = 3 ^ 2 - 3 ^ 1(n = 3)
- 2 = 3 ^ 1 - 3 ^ 0(n = 2)
即为 3 ^ (n - 1) - 3 ^ (n - 2)
因此相对于左上角为基准点来说,右上角、左下角、右下角的位置可以通过该方法进行确定
- 而中心的位置我们也可以看出来距离为 3 ^ 2
因此该题距离已知道如何确定,并以此来进行后续递归即可
递归终止条件
条件为 n = 1 时,此时将当前的 x 和 y 的位置置为题目要求的字符 ‘X’ 即可
算法思路
- 由于此题的 n 不大于6,所以宽高不大于 3 的 6-1=5 即5次方,即243,因此初始化一个宽高为 250 的数组 a 即可
- 将数组 a 初始化为空格,比如 n = 4 时,3 ^ 3 = 27,因此将数组 a 宽27高27的位置全初始化为空格
- 进行递归,每次递归都往左上角、右上角、中心、左下角、右下角进行递归
- 输出数组 a
更多注释可查看下方的完整代码中,有助于理解
代码如下
#include <map>
#include <cmath>
#include <queue>
#include <stack>
#include <cstdio>
#include <vector>
#include <utility>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
/*
4
*/
using namespace std;
const int N = 1050;
const int inf = 1e9+7;
const int mod = 1e9+7;
const double pi = acos(-1.0);
const double eps = 1e-9;
typedef long long ll;
int n;
char a[250][250]; // 由于此题的 n 不大于6,所以宽高不大于 3 的 6-1=5 即5次方,即243
// cur 为传了几次,i 为传到序号为几的人手上
void dfs(int cur, int x, int y) {
// 最后一个图形就不用递归咯
if(cur == 1) {
a[x][y] = 'X';
return;
}
// 当为第 n 次时,总图形为 3 的 n - 1 次方的宽高,且右上角位置为 3 的 n - 1 次方减去 3 的 n - 2 次方,其他位置也是这个规律
int len = pow(3, cur - 1);
int sub = pow(3, cur - 2);
dfs(cur - 1, x, y); // 左上角
dfs(cur - 1, x, y + len - sub); // 右上角
dfs(cur - 1, x + sub, y + sub); // 正中心
dfs(cur - 1, x + len - sub, y); // 左下角
dfs(cur - 1, x + len - sub, y + len - sub); // 右下角
}
int main()
{
// 每个图形宽3高3,因此为 3 的 n - 1 次方的宽高总共
cin >> n;
int len = pow(3, n - 1);
for(int i = 0; i < len; i++) {
for(int j = 0; j < len; j++) {
a[i][j] = ' '; // 把该盒子都变为空格先
}
}
dfs(n, 0, 0);
for(int i = 0; i < len; i++) {
for(int j = 0; j < len; j++) {
cout << a[i][j];
}
cout << endl;
}
return 0;
}
最后
对我感兴趣的小伙伴可查看以下链接
- 我的掘金主页:https://juejin.cn/user/1302297507801358
- 博客主页:http://blog.zhangjiancong.top/
- 公众号:Smooth前端成长记录