这题考察使用递归绘制分形。观察样例:
n=1 的一个最基本的图案是:
/\
/__\
n=2 时,把三角形每个顶点用 n=1 的图案代替即得。
n=3 时,把三角形的每个顶点用 n=2 的图案代替即得。
同理…… n 的绘制需要三个 n-1 的绘制。
设横坐标从上往下,纵坐标从左往右。图案大小为 n 时,容易高(横坐标跨度)是 2^n ,发现底(纵坐标跨度)是 2^{n+1} 。
所以以 (x,y) 为左上角绘制一个大小为 n(n > 1) 的图案,等效于分别绘制:
n=1 时,只有八个下标,分别赋值 /
, \
, _
和即可。
这样生成时,右边可能会有多余的空格;观察发现,第 i 行右端点为 2^n+i ,所以每次输出到这个范围就停止即可。不要再输出右边多余的空格了。为了实现这个思路,可以先全铺满空格,只画 /\_
,然后第 i 行输出前 2^n+i 个字符即可。
题意格式这么表述含糊不是我的锅啊,是洛谷原题,要怪就怪洛谷出题人(逃
n=10 时, 2^{n+1}=2048, 注意数组大小谨防 RE。
技巧:可以用位运算 1<<(x)
快速计算 2^x 。
参考代码:
#include <bits/stdc++.h>
#define MAXC 4098
char m[MAXC][MAXC];
inline void bas(int i, int j)
{
m[i][j + 1] = m[i + 1][j] = '/';
m[i][j + 2] = m[i + 1][j + 3] = '\\';
m[i + 1][j + 1] = m[i + 1][j + 2] = '_';
}
inline void spr(int i, int j, int n)
{
if (n == 1)
{
bas(i, j);
return;
}
spr(i + (1 << (n - 1)), j, n - 1);
spr(i, j + (1 << (n - 1)), n - 1);
spr(i + (1 << (n - 1)), j + (1 << (n)), n - 1);
}
int n, l;
int main()
{
memset(m, ' ', sizeof m);
scanf("%d", &n);
spr(0, 0, n);
for (int i = 0; i < (1 << n); i++)
{
for (int j = 0; j < (1 << n) + i + 1; j++)
{
printf("%c", m[i][j]);
}
printf("\n");
}
return 0;
}