从最小三角形开始,每次把旧图放在上方居中和下方左右两份,迭代生成分形图案。
OJ: luogu
题目 ID: P1498
难度:入门
标签:递归分形字符串python
日期: 2026-07-15 22:30
题意
给定 n,输出对应大小的三角分形图腾。
思路
从 n=1 的基础图形开始:
text
/\
/__\每放大一层:
- 上半部分:旧图整体居中;
- 下半部分:左右各放一份旧图。
这样迭代到第 n 层即可。
也可以用递归(DFS)的视角看同一件事:n 层图腾由 1 个上方 和 2 个下方 的 n-1 层图腾组成,而最小单元就是上面那个两行四列的三角形。递归函数 dfs(x, y, level) 以 (x,y) 为底部中心画 level 层图腾,子图腾相对中心偏移 2^(level-1)。
Python 知识
- 字符串可以用
line + line拼接成左右两份。 " " * height用来补居中空格。- 输出时
rstrip()去掉右侧多余空格,但保留左侧缩进。
参考笔记:
/home/rainboy/mycode/hugo-blog/content/program_language/python/input_output_and_strings.md
代码
python
n = int(input())
picture = [
" /\\ ",
"/__\\",
]
for _ in range(2, n + 1):
height = len(picture)
top = [" " * height + line + " " * height for line in picture]
bottom = [line + line for line in picture]
picture = top + bottom
for line in picture:
print(line.rstrip())cpp
/**
* Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
* rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
* rainboy的学习导航网站: https://idx.roj.ac.cn
* create_at: 2026-07-27 00:00
* update_at: 2026-07-27 00:00
*/
#include <bits/stdc++.h>
using namespace std;
int n;
string pic[2500];
int main() {
cin >> n;
pic[0] = " /\\ ";
pic[1] = "/__\\";
int h = 2;
for (int k = 2; k <= n; k++) {
string tmp[2500];
for (int i = 0; i < h; i++) tmp[i] = pic[i];
for (int i = 0; i < h; i++) pic[i] = string(h, ' ') + tmp[i] + string(h, ' ');
for (int i = 0; i < h; i++) pic[i + h] = tmp[i] + tmp[i];
h *= 2;
}
for (int i = 0; i < h; i++) {
int pos = pic[i].find_last_not_of(' ');
cout << pic[i].substr(0, pos + 1) << endl;
}
return 0;
}代码 (DFS)
用递归分治从底部中心开始画图,无需维护行宽。
cpp
#include <bits/stdc++.h>
using namespace std;
int n;
char pic[1050][2050];
// 以 (x,y) 为"底部中心"画 level 层图腾
void dfs(int x, int y, int level) {
if (level == 1) { // 最小单元:2行4列
pic[x-1][y-1] = '/';
pic[x-1][y] = '\\';
pic[x][y-2] = '/';
pic[x][y-1] = '_';
pic[x][y] = '_';
pic[x][y+1] = '\\';
return;
}
int half = 1 << (level - 1); // 子图腾高/半宽 = 2^(level-1)
dfs(x - half, y, level - 1); // 上方
dfs(x, y - half, level - 1); // 左下方
dfs(x, y + half, level - 1); // 右下方
}
int main() {
cin >> n;
memset(pic, ' ', sizeof(pic));
int h = 1 << n; // 总高 2^n
dfs(h - 1, h, n); // 底部中心 (2^n-1, 2^n)
for (int i = 0; i < h; i++) {
int end = (1 << (n+1)) - 1;
while (pic[i][end] == ' ') end--;
for (int j = 0; j <= end; j++) cout << pic[i][j];
cout << endl;
}
return 0;
}复杂度
最终图形高度为
总结
字符画题最重要的是先找到“上一层如何拼成下一层”。这里就是上方居中、下方复制两份。