[코테] 백준 시물레이션과 구현 20327번 문제
20327번 : 배열 돌리기 6
문제 링크
https://www.acmicpc.net/problem/20327
문제 설명
크기가 2N×2N인 배열이 있을 때, 배열에 연산을 R번 적용하려고 한다. 연산은 8가지가 있고, 연산에는 단계 ℓ (0 ≤ ℓ < N)이 있다. 단계 ℓ은 배열을 부분 배열로 나눌때 사용하는 값이며, 부분 배열의 크기는 2ℓ×2ℓ가 되어야 한다. 단계는 연산을 수행할때마다 정한다.
다음은 크기가 23×23 배열을 단계 ℓ의 값에 따라 부분 배열로 나눈 것이다. 같은 부분 배열은 같은 색상으로 표시했다.
1번 연산은 각 부분 배열을 상하 반전시키는 연산이다.
2번 연산은 각 부분 배열을 좌우 반전시키는 연산이다.
3번 연산은 각 부분 배열을 오른쪽으로 90도 회전시키는 연산이다.
4번 연산은 각 부분 배열을 왼쪽으로 90도 회전시키는 연산이다.
5, 6, 7, 8번 연산은 부분 배열을 한 칸으로 생각하고 적용시킨다. 즉, 부분 배열의 안에 있는 값은 변하지 않는다.
5번 연산은 배열을 상하 반전시키는 연산이다.
6번 연산은 배열을 좌우 반전시키는 연산이다.
7번 연산은 오른쪽으로 90도 회전시키는 연산이다.
8번 연산은 왼쪽으로 90도 회전시키는 연산이다.
입력
첫째 줄에 N, R이 주어진다. 둘째 줄부터 2N개의 줄에 배열의 원소 A[i][j]가 주어진다. i번째 줄의 j번째 정수는 A[i][j]를 의미한다.
다음 R개의 줄에 배열에 적용시켜야 하는 연산이 한 줄에 하나씩 주어진다. 연산은 두 정수 k, ℓ로 이루어져 있고, k번 연산을 단계 ℓ로 적용한다는 의미이다.
출력
입력으로 주어진 배열에 R개의 연산을 순서대로 수행한 결과를 출력한다.
제한
- 1 ≤ N ≤ 7
- 1 ≤ R ≤ 1,000
- 1 ≤ k ≤ 8
- 0 ≤ ℓ < N
- -999 ≤ A[i][j] ≤ 999
문제풀이
배열 돌리기 3번 문제와 같이 입력받은 연산에 따라서 배열을 처리하면 되는데 조금 더 고난이도의 문제이다. 솔직히 얘기하면 5번부터는 다른분 코드를 좀 참고하였다 ㅎㅎ…
def rotation_arr(num, step, originArr) :
size = 2 ** N
offset = 2 ** step
# 각 부분 배열을 상하 반전
if num == 1 :
resultArr = [[0 for _ in range(size)] for _ in range(size)]
for i in range(size) :
if i % offset == 0 :
nIdx = i + offset - 1
resultArr[i] = originArr[nIdx]
nIdx -= 1
# 각 부분 배열을 좌우 반전
elif num == 2 :
resultArr = [[0 for _ in range(size)] for _ in range(size)]
for i in range(size) :
for j in range(size) :
if j % offset == 0 :
nIdx = j + offset - 1
resultArr[i][j] = originArr[i][nIdx]
nIdx -= 1
# 각 부분 배열을 오른쪽으로 90도 회전
elif num == 3 :
resultArr = [[0 for _ in range(size)] for _ in range(size)]
for i in range(0, size, offset) :
for j in range(0, size, offset) :
for r in range(offset) :
for c in range(offset) :
resultArr[i+r][j+c] = originArr[i+offset-c-1][j+r]
# 각 부분 배열을 왼쪽으로 90도 회전
elif num == 4 :
resultArr = [[0 for _ in range(size)] for _ in range(size)]
for i in range(0, size, offset) :
for j in range(0, size, offset) :
for r in range(offset) :
for c in range(offset) :
resultArr[i+r][j+c] = originArr[i+c][j+offset-r-1]
# 부분 배열을 한 칸으로 생각, 배열을 상하 반전
elif num == 5 :
resultArr = [[0 for _ in range(size)] for _ in range(size)]
for i in range(0, size, offset) :
for j in range(0, size, offset) :
for r in range(offset) :
for c in range(offset) :
resultArr[i+r][j+c] = originArr[size-offset-i+r][j+c]
# 부분 배열을 한 칸으로 생각, 배열을 좌우 반전
elif num == 6 :
resultArr = [[0 for _ in range(size)] for _ in range(size)]
for i in range(0, size, offset) :
for j in range(0, size, offset) :
for r in range(offset) :
for c in range(offset) :
resultArr[i+r][j+c] = originArr[i+r][size-offset-j+c]
# 부분 배열을 한 칸으로 생각, 배열을 오른쪽으로 90도 회전
elif num == 7 :
resultArr = [[0 for _ in range(size)] for _ in range(size)]
for i in range(0, size, offset) :
for j in range(0, size, offset) :
for r in range(offset) :
for c in range(offset) :
resultArr[i+r][j+c] = originArr[size-offset-j+r][i+c]
# 부분 배열을 한 칸으로 생각, 왼쪽으로 90도 회전
elif num == 8 :
resultArr = [[0 for _ in range(size)] for _ in range(size)]
for i in range(0, size, offset) :
for j in range(0, size, offset) :
for r in range(offset) :
for c in range(offset) :
resultArr[i+r][j+c] = originArr[j+r][size-offset-i+c]
return resultArr
N, R = map(int, input().split())
arr = [list(map(int, input().split())) for _ in range(2**N)]
for _ in range(R) :
k, l = map(int, input().split())
arr = rotation_arr(k, l, arr)
for i in range(2 ** N) :
print(" ".join(map(str, arr[i])))
Comments