Python|图像绘制之十字图

欢迎点击「算法与编程之美」↑关注我们!

本文首发于微信公众号:"算法与编程之美",欢迎关注,及时了解更多此系列文章。

问题描述

小明为某机构设计了一个十字型的徽标(并非红十字会啊)。

输入:

一个正整数n(n< 30)表示要求打印图形的层数。

输出:

对应包围层数的该标志(中心固定)。

示例

输入:

1

输出:

解决方案

   这道题打印的是一个对称图形,而且对称轴很多,那么就可以利用图形的对称性进行思考。这里先上下对折,然后左右对折,最后45度角对折,得到一个直角三角形。如下图所示:

图 2.1变化过程

现在可以对被分成八份的图形(也就是直角三角形)进行大致的分析:

(注:行列从0开始)

前面两行都为(.)

偶数行的最后三个都为($)

偶数列大多都为($),除了特殊的几个位置(列值刚好比行值小1的时候)

其他都是(.)

根据这四个规律就可以打印分成八份的图形(直角三角形),再根据对称性就可以打印出题目要求的图形。但是,输出的时候是一行一行的输出的,如果成全是(.)的矩阵再遍历一个一个填入($)的话时间和空间复杂度就很大了。所以可以先把除直角三角形外的其他部分按照对称性先转换成直角三角形后按前面四个规律直接输出。

题目代码:

def aa(i, j, n):

    # 利用上下对称转换

    if i >=  (m+1)/2:

        i = m-1-i

    # 利用左右对称转换

    if j >=  (m+1)/2:

        j = m-1-j

    # 利用45度角对称转换

    if j > i:

        i, j = j, i

    # 四个角2*2的都为(.)的矩形

    if i <= 1  and j <= 1:

        return '.'

    # 偶数行最后的三个$和偶数列前面几个$

    elif (i % 2 ==  0 and j+2 >= i) or (j % 2 == 0 and j+1 != i):

        return '$'

    # 其他的都是点

    else:

        return '.'

 

 

n = int(input())

# 长宽的值

m = n*4+5

for i in range(m):

    for j in  range(m):

        print(aa(i,  j, n), end='')

    # 注意换行

    print('')

注意:上面三个利用对称关系转换的代码是有一定的次序的,前两个可以随意更换位置,但第三个必须放在前两个后面,否则后面的代码全部都要进行更换。

结语

    基本上绝大部分类似这种输出一个由几个字符组成的对称图形的题都可以先利用对称性把图形‘缩小’,这样可以很容易找到一定的规律并且这种规律大多都不繁杂。当然这种题也不一定要利用对称性把图形‘缩小’到最小,可能中间的某个图形就能找到十分简单的规律,或者直接寻找整个图形的某些规律。

END

编  辑   |   王楠岚

责  编   |   周茂林

 where2go 团队


   

微信号:算法与编程之美          

长按识别二维码关注我们!

温馨提示:点击页面右下角“写留言”发表评论,期待您的参与!期待您的转发!

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

算法与编程之美

欢迎关注『算法与编程之美』

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值