206. 2013年蓝桥杯省赛 - 打印十字图(困难)- 模拟
206. 打印十字图(模拟)
1. 2013年蓝桥杯省赛 - 打印十字图(困难)
标签:2013
模拟
省赛
1.1 题目描述
小明为某机构设计了一个十字型的徽标(并非红十字会啊),如下所示(可参见下图)
对方同时也需要在电脑 dos 窗口中以字符的形式输出该标志,并能任意控制层数。
为了能准确比对空白的数量,程序要求对行中的空白以句点(.)代替。
1.2 输入描述
输入一个正整数 n (n < 30)n (n < 30) 表示要求打印图形的层数。
1.3 输出描述
输出对应包围层数的该标志。
1.4 输入输出样例
示例:
输入
1
输出
..$$$$$..
..$...$..
$$$.$.$$$
$...$...$
$.$$$$$.$
$...$...$
$$$.$.$$$
..$...$..
..$$$$$..
1.5 运行限制
- 最大运行时间:1s
- 最大运行内存: 64M
2. 算法设计思路
2.1 图案构造逻辑
观察例图,我们会发现整个图案是 中心对称 的(即上下左右对称)。因此,我们只需要 构造左上角图案的一部分(第二象限),其余部分通过对称复制生成。
我们将整个图案看作是一个正方形的二维数组,其大小为 a × a
,其中:
a = 2 n + 3 a = 2n + 3 a=2n+3
2.2 使用二维列表模拟图案(字符画)
由上图可知,我们可将这个图案拆为三部分:横线三角形、竖线三角形、对角线,代码如下所示。
# 开始绘图
for i in range(0, a, 2):# 画横线dp[i][i + 2:a] = ['$'] * (a - i - 2)# 画竖线for j in range(i + 2, a):dp[j][i] = '$'# 画对角线if i != 0:dp[i][i - 1] = dp[i][i] = dp[i - 1][i] = '$'
2.3 图案镜像复制
利用对称性:
- 上半部分通过将每一行左半 + 右半逆序拼接;
- 下半部分是上半部分的镜像,直接倒序输出即可。
3. 代码实现
n = int(input())# 先画第二象限
# 生成完整十字图的1/2边长
a = n * 2 + 3
# 生成底图
dp = [['.'] * a for _ in range(a)]# 开始绘图
for i in range(0, a, 2):# 画横线dp[i][i + 2:a] = ['$'] * (a - i - 2)# 画竖线for j in range(i + 2, a):dp[j][i] = '$'# 画对角线if i != 0:dp[i][i - 1] = dp[i][i] = dp[i - 1][i] = '$'# 输出上半部分(包括x轴)
for s in dp:print(''.join(s + s[a - 2::-1]))# 输出下半部分
for s in dp[a - 2::-1]:print(''.join(s + s[a - 2::-1]))
4. 复杂度分析
- 时间复杂度: O ( n 2 ) O(n^2) O(n2),因为我们绘制一个约为 4 n 2 4n^2 4n2 大小的图案矩阵。
- 空间复杂度: O ( n 2 ) O(n^2) O(n2),用于二维字符数组的存储。