deque对象支持旋转操作,可以将元素向左或向右循环移动。
例如:
from collections import deque
dq = deque([1, 2, 3, 4])
dq.rotate(1)
执行后dq变为:
[4, 1, 2, 3]
元素向右移动了一位,最后一个元素到了最前面。
在这个问题中,我们有一个n*n的矩阵,利用deque来表示,旋转操作可以使列循环移动:
原矩阵:
[[1, 2, 3]
[4, 5, 6]]
旋转后:
[[3, 1, 2]
[6, 4, 5]]
第0列移动到最后,第2列移动到最前。
通过n次旋转,我们可以得到矩阵每种列排列顺序。
这样在每次旋转中计算対角线元素和,最终得到最大值。
所以这个rotate操作实现了按列的循环移位。
利用这个操作,结合记录最大对角线和,我们可以高效解决这个问题。
在deque的rotate方法中,正数表示向右旋转,负数表示向左旋转。
from collections import deque
dq = deque([1, 2, 3, 4])
向右旋转(rotate正数):
dq.rotate(1) # [4, 1, 2, 3]
dq.rotate(2) # [3, 4, 1, 2]
元素向右移动,最后一个元素moviel到最前面。
向左旋转(rotate负数):
dq.rotate(-1) # [2, 3, 4, 1]
dq.rotate(-2) # [3, 4, 1, 2]
元素向左移动,第一个元素moviel到最后面。
也就是:
正数表示向右循环旋转
负数表示向左循环旋转
在这个问题中,我们可以通过正数旋转实现按列循环移位,负数旋转实现按行循环移位。
那么向右/左旋转有什么不同呢?
向右旋转每次移动列
向左旋转每次移动行
旋转方向改变了移动的轴(列/行),但求最大对角线元素之和的逻辑是相同的。
例题(蓝桥杯3961题)求矩阵对角线最值
from collections import deque # 需要用到 deque 的 rotate(旋转) 方法
"""
示例: dq = deque([1, 5, 3, 9])
dq.rotate(1) 表示向右旋转 1 个单位
旋转后: [9, 1, 5, 3] 1 5 3 会右移 1 个单位, 而最后的元素 9 会被右移至第一位(因为右边没位置了,
所以会顶替第一个位置)
在问题的示例中,[
[7, 8, 9],
[4, 5, 7],
[1, 2, 3]]
向右旋转 1 位为:[
[1, 2, 3],
[7, 8, 9],
[4, 5, 7]]
我们可以旋转 n 次操作, 来获取每次旋转的对角线值
"""
n = int(input())
# n * n 方阵, 用 双向队列(deque) 方便 旋转操作(rotate)
rubiks_cube = deque(list(map(int, input().split())) for _ in range(n))
# max_diagonal 存储最大的正对角线值
max_diagonal = 0
# 对每次旋转求最大对角线
for _ in range(n):
i, cur_val = 0, 0
# 遍历方阵获取对角线值
while i < len(rubiks_cube):
cur_val += rubiks_cube[i][i]
i += 1
# 求最大的对角线
max_diagonal = max(cur_val, max_diagonal)
# 右旋转 1 单位
rubiks_cube.rotate(1)
print(max_diagonal)