-- 예전 기록/BOJ

[ BOJ ] 16927 : 배열 돌리기 2 ( GOLD 5 ) / Python

rejo 2024. 2. 15. 17:13

크기가 N×M인 배열이 있을 때, 배열을 돌려보려고 한다. 배열은 다음과 같이 반시계 방향으로 돌려야 한다.

A[1][1] ← A[1][2] ← A[1][3] ← A[1][4] ← A[1][5]
   ↓                                       ↑
A[2][1]   A[2][2] ← A[2][3] ← A[2][4]   A[2][5]
   ↓         ↓                   ↑         ↑
A[3][1]   A[3][2] → A[3][3] → A[3][4]   A[3][5]
   ↓                                       ↑
A[4][1] → A[4][2] → A[4][3] → A[4][4] → A[4][5]

예를 들어, 아래와 같은 배열을 2번 회전시키면 다음과 같이 변하게 된다.

1 2 3 4       2 3 4 8       3 4 8 6
5 6 7 8       1 7 7 6       2 7 8 2
9 8 7 6   →   5 6 8 2   →   1 7 6 3
5 4 3 2       9 5 4 3       5 9 5 4
 <시작>         <회전1>        <회전2>

배열과 정수 R이 주어졌을 때, 배열을 R번 회전시킨 결과를 구해보자.

입력

첫째 줄에 배열의 크기 N, M과 수행해야 하는 회전의 수 R이 주어진다.

둘째 줄부터 N개의 줄에 배열 A의 원소 Aij가 주어진다.

출력

입력으로 주어진 배열을 R번 회전시킨 결과를 출력한다.

풀이 과정

이전에 배열 돌리기 1을 푼 적이 있다. 이 코드를 수정하여 풀이했다.

https://readytojoin.tistory.com/entry/BOJ-16926-%EB%B0%B0%EC%97%B4-%EB%8F%8C%EB%A6%AC%EA%B8%B0-1-SILVER-1-Python

 

[ BOJ ] 16926 : 배열 돌리기 1 ( SILVER 1 ) / Python

문제 크기가 N×M인 배열이 있을 때, 배열을 돌려보려고 한다. 배열은 다음과 같이 반시계 방향으로 돌려야 한다. A[1][1] ← A[1][2] ← A[1][3] ← A[1][4] ← A[1][5] ↓ ↑ A[2][1] A[2][2] ← A[2][3] ← A[2][4] A[2

readytojoin.tistory.com

 

돌리는 횟수 R의 제한이 크므로, 모듈러 연산으로 횟수를 줄여야 한다. 

한 가장자리가 정확히 한 바퀴를 회전해 제자리로 돌아올 때의 횟수를 모두 안다면 모듈러 연산을 통해 횟수를 크게 줄일 수 있다. 그리고 그 횟수는 ((가장자리의 가로 크기 - 1) * 2) + ((가장자리의 세로 크기 - 1) * 2) 이다.

 

(가장자리 가로 크기 - 1)로 2번, (가장자리 세로 크기 - 1)로 2번

 

전체를 한 번 회전하고 그 과정을 R번 반복했던 이전 코드를 수정하여, 한 가장자리를 R % ( ((가장자리의 가로 크기 - 1) * 2) + ((가장자리의 세로 크기 - 1) * 2) ) 번 완전히 회전하는 코드로 풀이했다.

 

import sys
input = sys.stdin.readline

n, m, r = map(int, input().rstrip().split())
arr = [list(map(int, input().rstrip().split())) for _ in range(n)]

row = [1, 0, -1, 0]
col = [0, 1, 0, -1]

left = 0
right = m - 1
up = 0
down = n - 1
while left < right and up < down:
    for _ in range(r%((right-left)*2+(down-up)*2)):
        now = [left, up]
        now_tmp = arr[left][up]
        dir = 0
        while True:
            now[0] += row[dir]
            now[1] += col[dir]

            go = now_tmp
            now_tmp = arr[now[0]][now[1]]
            arr[now[0]][now[1]] = go

            if (dir == 0 and now[0] == down) or (dir == 1 and now[1] == right) or (dir == 2 and now[0] == up) or (dir == 3 and now[1] == left):
                dir = (dir + 1) % 4
            
            if now[0] == left and now[1] == up: break

    left += 1
    right -= 1
    up += 1
    down -= 1


for i in range(n): print(' '.join(map(str, arr[i])))