16926 배열 돌리기

Yunes·2023년 10월 29일
0
post-thumbnail

문제

크기가 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번 회전시킨 결과를 출력한다.

제한

2 ≤ N, M ≤ 300
1 ≤ R ≤ 1,000
min(N, M) mod 2 = 0
1 ≤ Aij ≤ 108

접근 방법

  • 행렬을 껍질별로 추출한다.
  • 덱으로 껍질을 감싸고 deque.rotate() 로 회전시킨다.
  • 회전한 껍질을 다시 행렬로 결합한다.

현재까지 matrix 관련해서는 transpose, reverse, 90 degree rotate 만 케이스를 접해봤는데 각 껍질별로 회전하는 문제를 처음 접하여 기록하고자 한다.

코드

import sys
from collections import deque

# N, M - 배열의 크기, R - 수행해야 하는 회전의 수
N, M, R = map(int, sys.stdin.readline().rstrip().split())

matrix = []

for i in range(N):
  matrix.append([int(val) for val in list(sys.stdin.readline().rstrip().split())])


def extract_shells(matrix):
  shells = []
    
  # 반복하여 각 쉘을 추출
  for shell in range(min(N, M) // 2):
    shell_coords = []
    
    # 상단 가로
    for i in range(shell, M - shell):
      shell_coords.append(matrix[shell][i])
    
    # 오른쪽 세로
    for i in range(shell + 1, N - shell):
      shell_coords.append(matrix[i][M - shell - 1])
    
    # 하단 가로
    if shell < N - shell - 1:
      for i in range(M - shell - 2, shell - 1, -1):
        shell_coords.append(matrix[N - shell - 1][i])
    
    # 왼쪽 세로
    if shell < M - shell - 1:
      for i in range(N - shell - 2, shell, -1):
        shell_coords.append(matrix[i][shell])
    
    shells.append(shell_coords)
  
  return shells

def combine_shells(shells, rows, cols):
  matrix = [[0] * cols for _ in range(rows)]
  shell_idx = 0
    
  for shell in range(min(rows, cols) // 2):
    shell_coords = shells[shell_idx]
    
    # 상단 가로
    for i in range(shell, cols - shell):
      matrix[shell][i] = shell_coords.pop(0)
    
    # 오른쪽 세로
    for i in range(shell + 1, rows - shell):
      matrix[i][cols - shell - 1] = shell_coords.pop(0)
    
    # 하단 가로
    if shell < rows - shell - 1:
      for i in range(cols - shell - 2, shell - 1, -1):
        matrix[rows - shell - 1][i] = shell_coords.pop(0)
    
    # 왼쪽 세로
    if shell < cols - shell - 1:
      for i in range(rows - shell - 2, shell, -1):
        matrix[i][shell] = shell_coords.pop(0)
    
    shell_idx += 1
  
  return matrix


shells = extract_shells(matrix)
result = []

for stack in shells:
  deq = deque(stack)
  deq.rotate(-R)
  result.append(list(deq))

convertedMatrix = combine_shells(result, N, M)

for row in convertedMatrix:
  for col in row:
    print(col, end=' ')
  print()
profile
미래의 나를 만들어나가는 한 개발자의 블로그입니다.

0개의 댓글