문제 링크 : https://www.acmicpc.net/problem/16935
문제
크기가 N×M인 배열이 있을 때, 배열에 연산을 R번 적용하려고 한다. 연산은 총 6가지가 있다.
1번 연산은 배열을 상하 반전시키는 연산이다.
1
2
3
4
5
6
7
|
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
2
3
4
5
6
7
|
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
2
3
4
5
6
7
|
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
2
3
4
5
6
7
|
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
2
3
4
5
6
|
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번으로 이동시키는 연산이다.
1
2
3
4
5
6
7
|
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번으로 이동시키는 연산이다.
1
2
3
4
5
6
7
|
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$의 원소 $A_{ij}$가 주어진다.
마지막 줄에는 수행해야 하는 연산이 주어진다. 연산은 공백으로 구분되어져 있고, 문제에서 설명한 연산 번호이며, 순서대로 적용시켜야 한다.
출력
입력으로 주어진 배열에 $R$개의 연산을 순서대로 수행한 결과를 출력한다.
제한
- $2 \leq N, M \leq 100$
- $1 \leq R \leq 1,000$
- $N$, $M$은 짝수
- $1 \leq A_{ij} \leq 10^8$
소스 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
import sys
input = sys.stdin.readline
n, m, r = map(int, input().split())
arr = [[int(x) for x in input().split()] for _ in range(n)]
options = [int(x) for x in input().split()]
for option in options:
if option == 1:
arr = arr[::-1] # 상하 반전
elif option == 2:
arr = list(map(lambda x: x[::-1], arr)) # 좌우 반전
elif option == 3:
arr = list(zip(*arr[::-1])) # 오른쪽으로 90도 회전
n, m = m, n # 행, 열 사이즈 스왑
elif option == 4:
arr = list(map(list, zip(*arr)))[::-1] # 왼쪽으로 90도 회전
n, m = m, n
else:
arr1 = map(lambda x: x[:m//2], arr[:n//2]) # 1사분면
arr2 = map(lambda x: x[m//2:], arr[:n//2]) # 2사분면
arr3 = map(lambda x: x[:m//2], arr[n//2:]) # 3사분면
arr4 = map(lambda x: x[m//2:], arr[n//2:]) # 4사분면
if option == 5: # 시계 방향 사분면 회전
arr = list(zip(arr3, arr1)) + list(zip(arr4, arr2))
elif option == 6: # 반시계 방향 사분면 회전
arr = list(zip(arr2, arr4)) + list(zip(arr1, arr3))
arr = list(map(lambda x: x[0]+x[1], arr))
for row in arr:
print(*row)
|
풀이
후기
좀 귀찮은 문제였는데, 깔끔하게 구현해 보려고 노력했다. 파이썬 리스트컴프리헨션을 연습하기 좋은 문제였다.