문제
크기가 N×M 크기인 배열 A가 있을때, 배열 A의 값은 각 행에 있는 모든 수의 합 중 최솟값을 의미한다. 배열 A가 아래와 같은 경우 1행의 합은 6, 2행의 합은 4, 3행의 합은 15이다. 따라서, 배열 A의 값은 4이다.
1 2 3
2 1 1
4 5 6
예를 들어, 배열 A의 크기가 6×6이고, 회전 연산이 (3, 4, 2)인 경우에는 아래 그림과 같이 회전하게 된다.
A[1][1] A[1][2] → A[1][3] → A[1][4] → A[1][5] → A[1][6]
↑ ↓
A[2][1] A[2][2] A[2][3] → A[2][4] → A[2][5] A[2][6]
↑ ↑ ↓ ↓
A[3][1] A[3][2] A[3][3] A[3][4] A[3][5] A[3][6]
↑ ↑ ↓ ↓
A[4][1] A[4][2] A[4][3] ← A[4][4] ← A[4][5] A[4][6]
↑ ↓
A[5][1] A[5][2] ← A[5][3] ← A[5][4] ← A[5][5] ← A[5][6]
A[6][1] A[6][2] A[6][3] A[6][4] A[6][5] A[6][6]
배열은 회전 연산을 수행할 수 있다. 회전 연산은 세 정수 (r, c, s)로 이루어져 있고, 가장 왼쪽 윗 칸이 (r-s, c-s), 가장 오른쪽 아랫 칸이 (r+s, c+s)인 정사각형을 시계 방향으로 한 칸씩 돌린다는 의미이다. 배열의 칸 (r, c)는 r행 c열을 의미한다. 회전 연산이 두 개 이상이면, 연산을 수행한 순서에 따라 최종 배열이 다르다.
다음은 배열 A의 크기가 5×6이고, 회전 연산이 (3, 4, 2), (4, 2, 1)인 경우의 예시이다.
배열 A에 (3, 4, 2), (4, 2, 1) 순서로 연산을 수행하면 배열 A의 값은 12, (4, 2, 1), (3, 4, 2) 순서로 연산을 수행하면 15 이다.
배열 A와 사용 가능한 회전 연산이 주어졌을 때, 배열 A의 값의 최솟값을 구해보자. 회전 연산은 모두 한 번씩 사용해야 하며, 순서는 임의로 정해도 된다.
입력
첫째 줄에 배열 A의 크기 N, M, 회전 연산의 개수 K가 주어진다.
둘째 줄부터 N개의 줄에 배열 A에 들어있는 수 A[i][j]가 주어지고, 다음 K개의 줄에 회전 연산의 정보 r, c, s가 주어진다.
출력
배열 A의 값의 최솟값을 출력한다.
제한
- 3 ≤ N, M ≤ 50
- 1 ≤ K ≤ 6
- 1 ≤ A[i][j] ≤ 100
- 1 ≤ s
- 1 ≤ r-s < r < r+s ≤ N
- 1 ≤ c-s < c < c+s ≤ M
문제가 상당히 귀찮아 보여서 안 풀고 있었는데 오늘 드디어 풀었다. 문제가 어렵지는 않았는데 진짜 귀찮긴 했다. N, M이 50까지고 K도 6까지라서 DFS를 이용해서 완전 탐색을 해도 시간 제약 안에 해결 가능해 보였다.
DFS를 사용해서 사용할 수 있는 회전 연산들을 순열로 만들어서 회전시키고 마지막에 배열 값을 계산했다. 그중에 가장 작은 값을 정답을 출력하면 된다.
배열을 회전시키는 게 생각보다 어려웠다. 어찌어찌 회전시키기는 했는데 더 야무지게 하는 방법이 무조건 있을 것 같다. 그리고 DFS를 하는 도중에 배열을 회전시키면 배열의 상태를 다시 돌려놔야 한다. 이걸 없애보고 싶어서 STL stack을 사용해서 풀었었는데 잘 되지 않아서 결국엔 임시 배열을 사용해 상태를 복원시키는 방법을 사용했다.
후기)
그냥 구현이 귀찮은 문제지 어려운 문제는 아니었던 것 같다.
'PS > 백준' 카테고리의 다른 글
[BOJ] 1746 듣보잡 (0) | 2022.02.03 |
---|---|
[BOJ] 1766 문제집 (7) | 2022.02.02 |
[BOJ] 2473 세 용액 (1) | 2022.01.31 |
[BOJ] 2623 음악프로그램 (1) | 2022.01.30 |
[BOJ] 17471 게리맨더링 (0) | 2022.01.29 |