Python|影像繪製之十字圖
- 2020 年 3 月 30 日
- 筆記
問題描述
小明為某機構設計了一個十字型的徽標(並非紅十字會啊)。
輸入:
一個正整數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+5for i in range(m): for j in range(m): print(aa(i, j, n), end='') # 注意換行 print('') |
---|
注意:上面三個利用對稱關係轉換的程式碼是有一定的次序的,前兩個可以隨意更換位置,但第三個必須放在前兩個後面,否則後面的程式碼全部都要進行更換。
結語
基本上絕大部分類似這種輸出一個由幾個字元組成的對稱圖形的題都可以先利用對稱性把圖形『縮小』,這樣可以很容易找到一定的規律並且這種規律大多都不繁雜。當然這種題也不一定要利用對稱性把圖形『縮小』到最小,可能中間的某個圖形就能找到十分簡單的規律,或者直接尋找整個圖形的某些規律。
END
編 輯 | 王楠嵐
責 編 | 周茂林
where2go 團隊