Noa's Blog

寫一題 python

在 zerojudge 上寫題目,手敲好快樂(我想手寫程式快變成類似針織的興趣了)。並發現 zerojudge 社群好活躍,隨時都有人在送出答案(包含凌晨三點)。

學到什麼

一、執行比較快的架構:先推邏輯,最後一次改矩陣(題目要求一秒但是十二毫秒就跑完了,非常自豪……)。

二、更改布林值的語法:

x = False
x = not x
print(x) # True

(不知道這樣寫時,本來用 1 和 -1,更改就是 *(-1) ,啊隨便啦。)

三、二維列表行列座標互換的寫法:

s = [[1,2,3],[4,5,6]]
R = len(s)
C = len(s[0])

# sol 1
new_s = [[0 for i in range(R)] for o in range(C)]
for i in range(C):
    for o in range(R):
        new_s[i][o] = s[o][i]

# sol 2:前者的簡化版
new_s = [[s[i][o] for i in range(R)] for o in range(C)]

# sol 3:用 zip()
new_s = [list(i) for i in zip(*s)]

小地方:如果它重複執行,R 和 C 會改變,須以 len(s) 和 len(s[0]) 取代之,否則造成 index out of range。

其中 zip() 回傳值是元組:

s1 = [1,2,3]
s2 = [4,5,6]
s3 = zip(s1,s2)

for i in s3:
    print(i) # (1, 4)(2, 5)(3, 6)

print(list(s3)) # [(1, 4),(2, 5),(3, 6)]

也可用在字典,如:

s1 = ["apple","banana"]
s2 = [2,3]
s3 = zip(s1,s2)

print(dict(s3)) # {"apple": 2, "banana": 3}

四、盡量避免在函式中使用全域變數,用到的變數都寫進參數更佳。


我的答案

a = [int(i) for i in input().split()]
R, C, M = a[0], a[1], a[2]
B = []
for i in range(R):
    a = [int(o) for o in input().split()]
    B.append(a)
oper = [int(i) for i in input().split()]
oper.reverse()

flip = False # 矩陣上下翻轉
oppo = False # 矩陣左右顛倒
transpose = False # 行列座標互換
for i in oper:
    if i == 1:
        flip = not flip
    else:
        transpose = not transpose # 逆時針旋轉90度 = 座標互換 + 上下翻轉
        flip, oppo = oppo, flip # 座標互換,先前的 flip 和 oppo 也互換
        flip = not flip

if transpose:
    newB = [[B[i][p] for i in range(R)] for p in range(C)]
    B = newB
if flip:
    B.reverse()
if oppo:
    for i in B:
        i.reverse()

print(len(B),len(B[0]))
for i in range(len(B)):
    print(*B[i])