1596. 南蛮图腾

这题考察使用递归绘制分形。观察样例:

n=1 的一个最基本的图案是:

/\ /__\

n=2 时,把三角形每个顶点用 n=1 的图案代替即得。

n=3 时,把三角形的每个顶点用 n=2 的图案代替即得。

同理…… n 的绘制需要三个 n-1 的绘制。

设横坐标从上往下,纵坐标从左往右。图案大小为 n 时,容易高(横坐标跨度)是 2^n ,发现底(纵坐标跨度)是 2^{n+1}

所以以 (x,y) 为左上角绘制一个大小为 n(n > 1) 的图案,等效于分别绘制:

  • (x,y+2^{n-1}) 为左上角,绘制 n-1 图案
  • (x+2^n,y) 为左上角,绘制 n-1 图案
  • (x+2^n,y+2^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; }