- 첫 플래티넘 문제/ 배열 돌리기 3번과 달리 이 문제는 R이 2000000이기 때문에 새로운 아이디어가 필요함
전반적인 구현 흐름
- 우선 기존 arr를 1, 2, 3, 4 부분으로 나누어 origin_arr에 저장함
- status_updown, status_leftright, status_rotate (순서대로 각 origin_arr의 상하반전, 좌우반전, 회전 상태를 나타냄)를 이용하여 각 origin_arr의 상태를 갱신함
- mini_arr는 기존 arr의 mini 버전임. [[0, 1], [2, 3]] 형태로 구성돼있음
- cmds의 cmd를 모두 실행시켜주어 mini_arr를 변경해주고, 그 과정에서 갱신된 status 변수들을 기반으로 상하반전, 좌우반전, 회전 상태를 orgin_arr에 적용해줌
- final_arr에 mini_arr, origin_arr의 변경 상태를 최종적으로 저장해줌
- 이런식으로 구현을 해줌으로써 R번의 연산 동안 크기가 작은 mini_arr만 변경시켜주고 마지막에만 mini_arr, origin_arr의 변경상태를 final_arr에 저장해줌으로써 시간 단축을 할 수 있음
cmd_1()
- 상하반전 연산
- 만약 배열이 90도 회전된 상태 (status_rotate % 2가 1인 경우)라면 origin_arr 기준으로 봤을 때, 상하반전이 좌우반전이 되고 좌우반전이 상하반전이 됨
-> 배열이 90도 (또는 270도) 회전된 상태라면 status_leftright를 toggle해줌
-> 그렇지 않다면 status_updown을 toggle해줌
- mini_arr[0], mini_arr[1] = mini_arr[1], mini_arr[0]를 통해 mini_arr에서 상하반전 수행
cmd_2()
- 좌우반전 연산
- 만약 배열이 90도 회전된 상태 (status_rotate % 2가 1인 경우)라면 origin_arr 기준으로 봤을 때, 상하반전이 좌우반전이 되고 좌우반전이 상하반전이 됨
-> 배열이 90도 (또는 270도) 회전된 상태라면 status_updown를 toggle해줌
-> 그렇지 않다면 status_leftright을 toggle해줌
- mini_arr[0][1], mini_arr[0][0] = mini_arr[0][0], mini_arr[0][1]; mini_arr[1][1], mini_arr[1][0] = mini_arr[1][0], mini_arr[1][1]를 통해 mini_arr에서 좌우반전 수행
cmd_3()
- 오른쪽으로 90도 회전 연산
- status_rotate = (status_rotate + 1) % 4를 수행하여 status 변수 갱신
- cmd_5() 호출
cmd_4()
- 왼족으로 90도 회전 연산
- status_rotate = (status_rotate - 1) % 4 (참고로 (-1) % 4는 3임)을 수행하여 status 변수 갱신
- cmd_6() 호출
cmd_5()
- 1->2, 2->4, 3->1, 4->3 연산 (mini_arr 기준으로 보면 오른쪽으로 90도 회전 연산임)
cmd_6()
- 1->3, 2->1, 3->4, 4->2 연산 (mini_arr 기준으로 보면 왼쪽으로 90도 회전 연산임)
rotation(src_arr)
- origin_arr의 원소를 회전해줌
- origin_arr별 오른쪽으로 90도 회전 연산
Source Code
import sys
from collections import deque
def cmd_1():
global status_updown; global status_leftright; global status_rotate
if status_rotate % 2:
status_leftright = not status_leftright
else:
status_updown = not status_updown
mini_arr[0], mini_arr[1] = mini_arr[1], mini_arr[0]
def cmd_2():
global status_updown; global status_leftright; global status_rotate
if status_rotate % 2:
status_updown = not status_updown
else:
status_leftright = not status_leftright
mini_arr[0][1], mini_arr[0][0] = mini_arr[0][0], mini_arr[0][1]
mini_arr[1][1], mini_arr[1][0] = mini_arr[1][0], mini_arr[1][1]
def cmd_3():
global status_rotate
status_rotate = (status_rotate + 1) % 4
cmd_5()
def cmd_4():
global status_rotate
status_rotate = (status_rotate - 1) % 4
cmd_6()
def cmd_5():
global mini_arr
tmp_mini_arr = [[0, 0], [0, 0]]
tmp_mini_arr[0][0] = mini_arr[1][0]
tmp_mini_arr[0][1] = mini_arr[0][0]
tmp_mini_arr[1][0] = mini_arr[1][1]
tmp_mini_arr[1][1] = mini_arr[0][1]
mini_arr = tmp_mini_arr
def cmd_6():
global mini_arr
tmp_mini_arr = [[0, 0], [0, 0]]
tmp_mini_arr[0][0] = mini_arr[0][1]
tmp_mini_arr[0][1] = mini_arr[1][1]
tmp_mini_arr[1][0] = mini_arr[0][0]
tmp_mini_arr[1][1] = mini_arr[1][0]
mini_arr = tmp_mini_arr
def rotation(src_arr):
dest_arr = [[0 for _ in range(len(src_arr))] for __ in range(len(src_arr[0]))]
for i in range(len(src_arr[0])):
for j in range(len(src_arr)):
dest_arr[i][j] = src_arr[len(src_arr) - j - 1][i]
return dest_arr
N, M, R = map(int, sys.stdin.readline()[:-1].split())
arr = []
for n in range(N):
arr.append(list(sys.stdin.readline()[:-1].split()))
cmds = list(map(int, sys.stdin.readline()[:-1].split()))
origin_arr = []
one = arr[:N//2]; two = arr[:N//2]; three = arr[N//2:]; four = arr[N//2:]
for i in range(N//2):
two[i] = deque(two[i]); four[i] = deque(four[i])
for _ in range(M//2):
one[i].pop(); two[i].popleft(); three[i].pop(); four[i].popleft()
two[i] = list(two[i]); four[i] = list(four[i])
origin_arr.append(one); origin_arr.append(two); origin_arr.append(three); origin_arr.append(four)
mini_arr = [[0, 1], [2, 3]]
status_updown = False; status_leftright = False; status_rotate = 0
for cmd in cmds:
if cmd == 1:
cmd_1()
elif cmd == 2:
cmd_2()
elif cmd == 3:
cmd_3()
elif cmd == 4:
cmd_4()
elif cmd == 5:
cmd_5()
elif cmd == 6:
cmd_6()
if status_updown:
for i in range(4):
origin_arr[i].reverse()
if status_leftright:
for i in range(4):
for j in range(len(origin_arr[i])):
origin_arr[i][j].reverse()
for _ in range(status_rotate):
for i in range(4):
origin_arr[i] = rotation(origin_arr[i])
final_arr = []
final_arr.extend(origin_arr[mini_arr[0][0]])
final_arr.extend(origin_arr[mini_arr[1][0]])
for i in range(len(final_arr) // 2):
final_arr[i].extend(origin_arr[mini_arr[0][1]][i])
final_arr[i + len(final_arr) // 2].extend(origin_arr[mini_arr[1][1]][i])
for i in range(len(final_arr)):
print(" ".join(final_arr[i]))