https://www.acmicpc.net/problem/17406
문제
크기가 N×M 크기인 배열 A가 있을때, 배열 A의 값은 각 행에 있는 모든 수의 합 중 최솟값을 의미한다. 배열 A가 아래와 같은 경우 1행의 합은 6, 2행의 합은 4, 3행의 합은 15이다. 따라서, 배열 A의 값은 4이다.
1 2 3
2 1 1
4 5 6
배열은 회전 연산을 수행할 수 있다. 회전 연산은 세 정수 (r, c, s)로 이루어져 있고, 가장 왼쪽 윗 칸이 (r-s, c-s), 가장 오른쪽 아랫 칸이 (r+s, c+s)인 정사각형을 시계 방향으로 한 칸씩 돌린다는 의미이다. 배열의 칸 (r, c)는 r행 c열을 의미한다.
예를 들어, 배열 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]
회전 연산이 두 개 이상이면, 연산을 수행한 순서에 따라 최종 배열이 다르다.
다음은 배열 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
예제 입력 1
5 6 2
1 2 3 2 5 6
3 8 7 2 1 3
8 2 3 1 4 5
3 4 5 1 1 1
9 3 2 1 4 3
3 4 2
4 2 1
예제 출력 1
12
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
static int N; // 배열의 크기
static int M; // 배열의 크기
static int K; // 회전 연산의 개수
static int[][] arr; // 배열
static int[][] turn; // 돌리기 연산에 대한 정보
static boolean[] done; // 배열 돌리기를 실행했는지 확인하는 배열
static int[] order; // 배열 돌리기 실행 순서
static int result = Integer.MAX_VALUE;
// 배열 돌리기
private static void turnArr(int[][] tmpArr, int r, int c, int s) {
for (int i = 1; i <= s; i++) { // 안쪽부터 바깥까지 한 겹씩 총 s겹 배열 돌리기
int tmp = tmpArr[r - i][c - i]; // 맨 앞의 수 기억
for (int j = 0; j < 2 * i; j++) { // 왼쪽
tmpArr[r - i + j][c - i] = tmpArr[r - i + j + 1][c - i];
}
for (int j = 0; j < 2 * i; j++) { // 밑
tmpArr[r + i][c - i + j] = tmpArr[r + i][c - i + j + 1];
}
for (int j = 0; j < 2 * i; j++) { // 오른쪽
tmpArr[r + i - j][c + i] = tmpArr[r + i - j - 1][c + i];
}
for (int j = 0; j < 2 * i; j++) { // 위
tmpArr[r - i][c + i - j] = tmpArr[r - i][c + i - j - 1];
}
tmpArr[r - i][c - i + 1] = tmp; // 기억해 둔 수 저장
}
}
private static void perm(int c) { // 순열 돌리기
if(c == K) {
// 배열 복사
int[][] tmpArr = new int[N + 1][M + 1];
for (int i = 0; i <= N; i++) {
tmpArr[i] = arr[i].clone();
}
// 순서대로 배열 돌리기
for (int i = 0; i < K; i++) {
turnArr(tmpArr, turn[order[i]][0], turn[order[i]][1], turn[order[i]][2]);
}
// 배열의 최솟값 구하기
int tmp = Integer.MAX_VALUE;
for (int i = 1; i <= N; i++) {
int sum = 0;
for (int j = 1; j <= M; j++) {
sum += tmpArr[i][j];
}
tmp = tmp < sum ? tmp : sum;
}
result = result < tmp ? result : tmp;
return;
}
for (int i = 0; i < K; i++) {
if(!done[i]) {
order[c] = i;
done[i] = true;
perm(c + 1);
done[i] = false;
}
}
}
public static void main(String[] args) throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
// N, M, K 입력
st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
K = Integer.parseInt(st.nextToken());
// N x M 크기 배열 선언
arr = new int[N + 1][M + 1];
// 배열 입력
for (int i = 1; i <= N; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 1; j <= M; j++) {
arr[i][j] = Integer.parseInt(st.nextToken());
}
}
// 배열 돌리기
turn = new int[K][3];
for (int i = 0; i < K; i++) {
st = new StringTokenizer(br.readLine());
turn[i][0] = Integer.parseInt(st.nextToken());
turn[i][1] = Integer.parseInt(st.nextToken());
turn[i][2] = Integer.parseInt(st.nextToken());
}
done = new boolean[K];
order = new int[K];
// 가능한 배열 돌리기 순서 모두 구하여 돌리기(순열)
perm(0);
// 출력
System.out.println(result);
}
}
'Problem Solving > BOJ' 카테고리의 다른 글
[백준, BOJ 14712] 넴모넴모 (Easy) (java) (0) | 2023.02.16 |
---|---|
[백준, BOJ 9229] 단어 사다리 (java) (0) | 2023.02.16 |
[백준, BOJ 1182] 부분수열의 합 (java) (0) | 2023.02.15 |
[백준, BOJ 16507] 어두운 건 무서워 (java) (0) | 2023.02.15 |
[백준, BOJ 6198] 옥상 정원 꾸미기 (java) (0) | 2023.02.15 |