🧫 문제 분석
✔️ 출처
📖 문제

DFS 로 풀었지만 정석은 bitmask인듯하다.
행 기준으로 현재 행을 뒤집는 경우와 뒤집지 않는 경우를 탐색하여 뒤집는 행을 갖는 조합을 만들고
열 기준으로도 조합을 만들어서
최종적으로 조합을 적용해 동전들을 뒤집고, target과 비교해서 맞다면
뒤집기 카운트와 비교해서 최솟값을 찾는다.
이문제를 풀면서
행과 열을 왔다갔다하면서 뒤집어야 나올 수 있는 target이 있을 줄 알았는데
그게 아니였다.
궁금해서 gpt 에게 물어봤다.
begin[i][j] ^ R[i] ^ C[j] == target[i][j]

🔅 문제 풀이
import java.util.*;
class Solution {
static int[][] otarget;
static int answer = Integer.MAX_VALUE;
static int size;
static int row, col;
public int solution(int[][] beginning, int[][] target) {
row = target.length;
col = target[0].length;
size = row * col;
otarget = target;
dfs2(beginning, 0, 0);
return answer == Integer.MAX_VALUE ? -1 : answer;
}
private void dfs2(int[][] map, int cnt, int depth) {
if (cnt >= answer) return;
if (depth == row + col) {
if (valid(map)) answer = Math.min(answer, cnt);
return;
}
// 행 부분 탐색
if (depth < row) {
// 뒤집지 않음
dfs2(map, cnt, depth + 1);
// 해당 행 뒤집음
int[][] newMap = cloneMap(map);
switching(newMap, depth, true);
dfs2(newMap, cnt + 1, depth + 1);
}
// 열 부분 탐색
else {
int idx = depth - row;
// 뒤집지 않음
dfs2(map, cnt, depth + 1);
// 해당 열 뒤집음
int[][] newMap = cloneMap(map);
switching(newMap, idx, false);
dfs2(newMap, cnt + 1, depth + 1);
}
}
private boolean valid(int[][] map) {
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
if (map[i][j] != otarget[i][j]) {
return false;
}
}
}
return true;
}
private int[][] cloneMap(int[][] map) {
int[][] tmp = new int[row][col];
for (int i = 0; i < row; i++) {
tmp[i] = map[i].clone();
}
return tmp;
}
private void switching(int[][] tmp, int line, boolean isRow) {
for (int i = 0; i < (isRow ? col : row); i++) {
// 한 행을 바꿈
if (isRow) {
tmp[line][i] = (tmp[line][i] + 1) % 2;
// 한 열을 바꿈
} else {
tmp[i][line] = (tmp[i][line] + 1) % 2;
}
}
}
}
❗ 오답노트 / 필요한 지식
- 항상 느끼지만 자꾸 하나씩 놓친다 .. 답답하다.
'programmers > Lv 3' 카테고리의 다른 글
| 봉인된 주문 [자바] (0) | 2025.11.19 |
|---|---|
| 최적의 행렬 곱셈 [자바] (0) | 2025.11.10 |
| 디스크 컨트롤러 [자바] (0) | 2025.10.22 |
| 연속 펄스 부분 수열의 합 [자바] (0) | 2025.02.26 |
| 섬 연결하기 [자바] (0) | 2025.02.25 |