시간 제한 2초, 메모리 제한 512MB
# 조건
- 크기가 N×M인 배열이 있을 때, 배열에 연산을 R번 적용하려고 한다.
- 연산은 총 6가지가 있다.
- 1번 연산은 배열을 상하 반전시키는 연산이다.
1 6 2 9 8 4 → 4 2 9 3 1 8
7 2 6 9 8 2 → 9 2 3 6 1 5
1 8 3 4 2 9 → 7 4 6 2 3 1
7 4 6 2 3 1 → 1 8 3 4 2 9
9 2 3 6 1 5 → 7 2 6 9 8 2
4 2 9 3 1 8 → 1 6 2 9 8 4
<배열> <연산 결과>
- 2번 연산은 배열을 좌우 반전시키는 연산이다.
1 6 2 9 8 4 → 4 8 9 2 6 1
7 2 6 9 8 2 → 2 8 9 6 2 7
1 8 3 4 2 9 → 9 2 4 3 8 1
7 4 6 2 3 1 → 1 3 2 6 4 7
9 2 3 6 1 5 → 5 1 6 3 2 9
4 2 9 3 1 8 → 8 1 3 9 2 4
<배열> <연산 결과>
- 3번 연산은 오른쪽으로 90도 회전시키는 연산이다.
1 6 2 9 8 4 → 4 9 7 1 7 1
7 2 6 9 8 2 → 2 2 4 8 2 6
1 8 3 4 2 9 → 9 3 6 3 6 2
7 4 6 2 3 1 → 3 6 2 4 9 9
9 2 3 6 1 5 → 1 1 3 2 8 8
4 2 9 3 1 8 → 8 5 1 9 2 4
<배열> <연산 결과>
- 4번 연산은 왼쪽으로 90도 회전시키는 연산이다.
1 6 2 9 8 4 → 4 2 9 1 5 8
7 2 6 9 8 2 → 8 8 2 3 1 1
1 8 3 4 2 9 → 9 9 4 2 6 3
7 4 6 2 3 1 → 2 6 3 6 3 9
9 2 3 6 1 5 → 6 2 8 4 2 2
4 2 9 3 1 8 → 1 7 1 7 9 4
<배열> <연산 결과>
- 5, 6번 연산을 수행하려면 배열을 크기가 N/2×M/2인 4개의 부분 배열로 나눠야 한다. 아래 그림은 크기가 6×8인 배열을 4개의 그룹으로 나눈 것이고, 1부터 4까지의 수로 나타냈다.
1 1 1 1 2 2 2 2
1 1 1 1 2 2 2 2
1 1 1 1 2 2 2 2
4 4 4 4 3 3 3 3
4 4 4 4 3 3 3 3
4 4 4 4 3 3 3 3
- 5번 연산은 1번 그룹의 부분 배열을 2번 그룹 위치로, 2번을 3번으로, 3번을 4번으로, 4번을 1번으로 이동시키는 연산이다.
3 2 6 3 1 2 9 7 → 2 1 3 8 3 2 6 3
9 7 8 2 1 4 5 3 → 1 3 2 8 9 7 8 2
5 9 2 1 9 6 1 8 → 4 5 1 9 5 9 2 1
2 1 3 8 6 3 9 2 → 6 3 9 2 1 2 9 7
1 3 2 8 7 9 2 1 → 7 9 2 1 1 4 5 3
4 5 1 9 8 2 1 3 → 8 2 1 3 9 6 1 8
<배열> <연산 결과>
- 6번 연산은 1번 그룹의 부분 배열을 4번 그룹 위치로, 4번을 3번으로, 3번을 2번으로, 2번을 1번으로 이동시키는 연산이다.
3 2 6 3 1 2 9 7 → 1 2 9 7 6 3 9 2
9 7 8 2 1 4 5 3 → 1 4 5 3 7 9 2 1
5 9 2 1 9 6 1 8 → 9 6 1 8 8 2 1 3
2 1 3 8 6 3 9 2 → 3 2 6 3 2 1 3 8
1 3 2 8 7 9 2 1 → 9 7 8 2 1 3 2 8
4 5 1 9 8 2 1 3 → 5 9 2 1 4 5 1 9
<배열> <연산 결과>
입력
- 첫째 줄에 배열의 크기 N, M과 수행해야 하는 연산의 수 R이 주어진다.
- 둘째 줄부터 N개의 줄에 배열 A의 원소 Aij가 주어진다.
- 마지막 줄에는 수행해야 하는 연산이 주어진다.
- 연산은 공백으로 구분되어져 있고, 문제에서 설명한 연산 번호이며, 순서대로 적용시켜야 한다.
출력
- 입력으로 주어진 배열에 R개의 연산을 순서대로 수행한 결과를 출력한다.
# 접근 방법
- 전형적인 구현 문제이다.
- 배열을 다루는 문제는 자주 나오는 것 같기에 연습해두면 좋을 것 같다.
- 평소에 하던대로 각 연산을 함수화 시키고 아래 로직에 따라 풀었다.
- 우선 command를 순회하며 실행할 명령어를 받으면서, 원본 arr을 new_arr에 deepcopy해준다.
- 명령어 1 - 상하반전
- 원본 arr의 첫 행 ~ 마지막 행을 new_arr의 마지막 행 ~ 첫행을 복붙해준다.
- 명령어 2 - 좌우 반전
- 원본 arr을 1칸씩 순회하며 같은 행, 반대 열의 값을 복사해준다.
- 명령어 3, 4
- zip 함수를 통해 시계, 반시계 방향으로 회전시켜준다.
- 이 때 중요한 점은 가로와 세로의 길이가 다를 수 있으므로 N, M을 변경해주어야 한다.
- 명령어 5, 6
- N//2, M//2를 최대 경계로 설정한다. 즉 문제 예시에서 1번 구역을 기준으로 복사해줄 것이다.
- 오른쪽 2번 구역은 1번 구역 기준 M//2 + j, 3번은 i + N//2, 4번은 i+N//2, j+M//2가 되므로 규칙에 맞게 잘 복사해주면 된다.
import sys
sys.stdin = open('input.txt')
input = sys.stdin.readline
from copy import deepcopy
# 1번 상하반전
# 2번 좌우반전
# 3번 오른쪽 90도
# 4번 왼쪽 90도
# 5번 N/2 x M/2 4개 나눠서 오른쪽
# 6번 왼쪽
def rotate1():
for i in range(N):
arr[i] = new_arr[N-i-1]
def rotate2():
for i in range(N):
for j in range(M):
arr[i][j] = new_arr[i][M-1-j]
def rotate3():
global arr, N, M
arr = list(map(list, zip(*arr[::-1])))
N, M = M, N
def rotate4():
global arr, N, M
arr = list(map(list, zip(*arr)))[::-1]
N, M = M, N
def rotate5():
global arr
for i in range(N//2):
for j in range(M//2):
arr[i][j] = new_arr[i+N//2][j]
arr[i][j+M//2] = new_arr[i][j]
arr[i+N//2][j+M//2] = new_arr[i][j+M//2]
arr[i+N//2][j] = new_arr[i+N//2][j+M//2]
def rotate6():
global arr
for i in range(N//2):
for j in range(M//2):
arr[i][j] = new_arr[i][j+M//2]
arr[i][j+M//2] = new_arr[i+N//2][j+M//2]
arr[i+N//2][j+M//2] = new_arr[i+N//2][j]
arr[i+N//2][j] = new_arr[i][j]
N, M, R = map(int, input().split())
arr = [list(map(int, input().split())) for _ in range(N)]
command = list(map(int, input().split()))
for c in command:
new_arr = deepcopy(arr)
if c == 1:
rotate1()
elif c == 2:
rotate2()
elif c == 3:
rotate3()
elif c == 4:
rotate4()
elif c == 5:
rotate5()
else:
rotate6()
for a in arr:
print(*a)
'ALGORITHM > 정렬, 탐색,구현' 카테고리의 다른 글
[백준 15489번] 파이썬 - 파스칼 삼각형 (1) | 2023.12.03 |
---|---|
[백준 9081번] 파이썬 - 단어 맞추기 (1) | 2023.12.02 |
[백준 1527번] 금민수의 개수 (1) | 2023.12.01 |
[백준 2343번] 파이썬 - 기타 레슨 (0) | 2023.11.29 |
[백준 16973번] 파이썬 - 직사각형 탈출 (1) | 2023.11.29 |