코딩테스트 파이썬/구현

16926 배열돌리기 재시도(-0)

백엔드 개발자 2021. 7. 22. 13:00

문제

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

배열과 정수 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

총 4단계로 돌리면 되겠다고 생각했다.

테두리마다 왼쪽, 아래쪽, 오른쪽, 위쪽

 이 때 겹치는 부분이 있으니까 기준을 정해야 된다. 한쪽 모서리끝에서 다른쪽 모서리끝 전까지로 나는 기준을 잡았다.

테두리의 개수를 구할 때 좀 생각을 잘해야 됐는데,

제한에  min(N, M) mod 2 = 0가 있다. 항상 작은수는 짝수라는 뜻이고, 직접 그려보면 더작은수의 짝수를 나누기 2하면

총 테두리의 개수가 나온다.

 

여기까지는 좋았으나, 배열을 돌리는 알고리즘을 생각해내지 못했다.

 

 출처 https://maeng2world.tistory.com/197

 

[백준 16926] 배열 돌리기1, 2

1. 문제 https://www.acmicpc.net/problem/16926 16926번: 배열 돌리기 1 크기가 N×M인 배열이 있을 때, 배열을 돌려보려고 한다. 배열은 다음과 같이 반시계 방향으로 돌려야 한다. A[1][1] ← A[1][2] ← A[1][..

maeng2world.tistory.com

deque()를 이용해서 테두리의 값들을 전부 집어넣고, rotate()함수를 사용해서 돌리고 다시 집어넣는 기발한 아이디어의 예시를 경험해 볼 수 있었다.

 

우선 테두리 처음좌표는 nx,ny=0,0 이고, 테두리가 들어갈 때마다 1씩 커진다.

그 후 범위를 잘 지정해서 들어가면 되는데,

 

한가지 발견한건 rotate()안에 음수가 들어가면 왼쪽으로 회전하고, 양수면 오른쪽으로 회전한다.

내가 참고한 분 같은 경우 테두리를 시계방향으로 큐에 넣어서 rotate(음수)를 사용하면 정상적으로 반시계방향으로 배열이 돌아간다.

 

하지만 나같은 경우 멋모르고 테두리를 반시계방향으로 큐에 집어넣었다. 이경우는 rotate(음수)를 사용하면 오히려 시계방향으로 돌아서 나는 rotate(양수)로 부호를 그대로 해서 값에 넣었다.

 

 

 

from collections import deque
# n,m,r 입력받기
n,m,r=map(int,input().split())
arr=[
list(map(int,input().split() )) for _ in range(n)  ]

def rotation(r):
   
global n,m,arr
    q=deque()
   
#돌릴 테두리 개수인 a구하기
   
count=min(n,m)//2
   
_width,_height=m,n#가로,세로
   
#처음 시작점
   
nx,ny=0,0
   
while count>=1:
       
#1 왼쪽
       
for i in range(_height-1):
            q.append(arr[ny+i][nx])
       
#2 아래쪽
       
for i in range(_width-1):
            q.append(arr[ny+_height-
1][nx+i])
       
#3 오른쪽
       
for i in range(_height-1):
            q.append(arr[ny+_height-
1-i][nx+_width-1])
       
#4 위쪽
       
for i in range(_width-1):
            q.append(arr[ny][nx+_width-
1-i])
        q.rotate(r)
       
# 1 왼쪽
       
for i in range(_height - 1):
            arr[ny + i][nx]=q.popleft()
       
# 2 아래쪽
       
for i in range(_width - 1):
            arr[ny+_height -
1][nx + i] = q.popleft()
       
# 3 오른쪽
       
for i in range(_height - 1):
            arr[ny+_height -
1 - i][nx+_width - 1] = q.popleft()
        
# 4 위쪽
       
for i in range(_width - 1):
            arr[ny][nx+ _width- i-
1] = q.popleft()

        nx+=
1
       
ny+=1
       
_width-=2
       
_height-=2
       
count = min(_width, _height) // 2

rotation(r)
for i in range(n):
   
print(*arr[i])