https://www.acmicpc.net/problem/16926
문제
크기가 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
예제 입력 1
4 4 2
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
예제 출력 1
3 4 8 12
2 11 10 16
1 7 6 15
5 9 13 14
복기
1. 못 풀어서 다른 사람들 풀이를 봤다... 배열의 인덱스 세팅하는게 너무 어렵다 ㅠㅠ. 확실히 골드는 어려워
2. 레이어별로, 왼오, 위아래를 돌면서 바꿔줘야 했다.
3. q.rotate() 를 활용하고, 양수를 넣으면 숫자만큼 오른쪽으로 한칸씩 이동한다.
솔루션
from collections import deque
N, M, R = map(int, input().split())
arr = [list(map(int, input().split())) for _ in range(N)]
q = deque()
min_dim = min(N, M)
# 레이어별로 돌면서 확인
for i in range(min_dim // 2):
# 현재 레이어의 전체 길이
total = (N -1 - 2 * i + M - 1 -2 * i) * 2
rotate_cnt = R % total # 실제 회전 횟수
q.extend([row[i] for row in arr[i:N-i-1]]) # 왼쪽
q.extend([arr[N-i-1][i:M-i-1]]) # 아래쪽
q.extend([row[M-i-1] for row in arr[i+1:N-i][::-1]]) # 오른쪽
q.extend(arr[i][i+1:M-i][::-1])
q.rotate(rotate_cnt)
# 레이어를 다시 배열에 삽입
for k in range(i, N-i-1):
arr[k][i] = q.popleft() # 왼쪽
for k in range(i, M-i-1):
arr[N-i-1][k] = q.popleft() # 아래쪽
for k in range(N-i-1, i, -1): # 오른쪽
arr[k][M-i-1] = q.popleft()
for k in range(M-i-1, i, -1): #위쪽
arr[i][k] = q.popleft()
for row in arr:
print(*row)
'Dev > Algorithm' 카테고리의 다른 글
[백준] #2178 미로 탐색 파이썬 (1) | 2025.01.14 |
---|---|
[백준] #8911 거북이 파이썬 (1) | 2025.01.10 |
[백준] #14889 스타트와 링크 파이썬 (2) | 2025.01.06 |
[백준] #11722 가장 긴 감소하는 부분 수열 파이썬 (1) | 2025.01.06 |
[백준] #2579 계단 오르기 파이썬 (2) | 2025.01.05 |
댓글