[백준] 16927 배열돌리기2 (Python)

박수련·2024년 2월 4일

https://www.acmicpc.net/problem/16927

2차원 배열을 각각의 링을 반시계 방향으로 r만큼 돌려 결과값을 반환하는 문제이다.

for 문을 돌면서 바깥링부터 안쪽링까지 회전을 진행한다.

첫 번째 링은 i=0으로 i는 현재 링의 바깥에 있는 링의 개수를 의미하며, 링의 가장 왼쪽 상단의 좌표는 (i, i)이다.
하나의 링을 1차원 배열로 나열했을 때의 길이는 2*(a+b)-4이다.
a, b는 링이 포함된 최소 크기의 직사각형의 세로, 가로 길이이다.

가장 먼저 시계 방향으로 링을 따라가며 graph[i]에 1차원 배열로 저장해주었다.

회전 횟수 rotate를 구한 뒤, graph[i][rotate]를 시작으로 링을 돌면서 result값에 회전한 값을 넣어주었다.

코드


  import sys

  input = sys.stdin.readline

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

  # graph에 각 링의 값들을 시계방향으로 넣기
  ring = min(n, m) // 2  # 링의 개수
  graph = [[] for _ in range(ring)]  # 각 링의 값들을 하나의 1차원 배열에 저장
  result = [[0] * m for _ in range(n)]  # 결과값 저장
  for i in range(ring):
      # 각 링의 시작점
      x = i
      y = i

      # 각 링들의 세로 가로 길이
      a = n - 2 * i
      b = m - 2 * i

      # 하나의 링들의 값을 1차원 배열에 저장(링의 길이: 2*(a+b)-4)
      for _ in range(2 * (a + b) - 4):
          # 꼭짓점에 도달했을 때 방향 바꿔주기
          if x == i and y == i:  # 왼쪽 상단
              dirct = "right"
          elif x == i and y == i + b - 1:  # 가장 오른쪽 상단
              dirct = "down"
          elif x == i + a - 1 and y == i + b - 1:  # 오른쪽 하단
              dirct = "left"
          elif x == i + a - 1 and y == i:  # 왼쪽 하단
              dirct = "up"

          graph[i].append(arr[x][y])

          # 방향에 따라 좌표값 이동시키기
          if dirct == "right":
              y += 1
          elif dirct == "down":
              x += 1
          elif dirct == "left":
              y -= 1
          elif dirct == "up":
              x -= 1

      # 1차원 배열에서 회전 시킨 후 result값에 저장
      rotate = r % (2 * (a + b) - 4)
      idx = rotate  # 회전수를 graph 배열의 인덱스로 사용

      x = i
      y = i
      for _ in range(2 * (a + b) - 4):
          # 꼭짓점에 도달했을 때 방향 바꿔주기
          if x == i and y == i:  # 왼쪽 상단
              dirct = "right"
          elif x == i and y == i + b - 1:  # 가장 오른쪽 상단
              dirct = "down"
          elif x == i + a - 1 and y == i + b - 1:  # 오른쪽 하단
              dirct = "left"
          elif x == i + a - 1 and y == i:  # 왼쪽 하단
              dirct = "up"

          result[x][y] = graph[i][idx]

          # 방향에 따라 좌표값 이동시키기
          if dirct == "right":
              y += 1
          elif dirct == "down":
              x += 1
          elif dirct == "left":
              y -= 1
          elif dirct == "up":
              x -= 1

          idx += 1

          # 링의 길이보다 커지면 0으로 할당
          if idx >= 2 * (a + b) - 4:
              idx = 0
	
  for i in range(n):
      for j in range(m):
          print(result[i][j], end=" ")
      print()

0개의 댓글