SWEA 5656. 벽돌 깨기
simulation
- 모든 경우의 수를 탐색하면서 최대로 제거할 수 있는 경우를 찾는다.
- 떨어뜨릴 수 있는 구슬 수만큼 재귀 함수를 수행한다.
- 제거되어야 할 벽돌의 위치를 queue에 넣어 이후에 해당 벽돌로 인해 제거되어야 할 벽돌들을 탐색한다.
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import java.io.*;
import java.util.*;
public class Solution {
static int N, M, X, res;
static int[][] board;
static int[] dx = { -1, 0, 1, 0 };
static int[] dy = { 0,-1, 0, 1 };
static void copy(int[][] src, int[][] dest) {
for (int i = 0; i < N; i++)
for (int j = 0; j < M; j++)
dest[i][j] = src[i][j];
}
static int countRemain() {
int cnt = 0;
for (int i = 0; i < N; i++)
for (int j = 0; j < M; j++)
if (board[i][j] != 0) cnt++;
return cnt;
}
static void go(int cnt) {
if (cnt >= X) {
res = Math.min(res, countRemain());
return;
}
int[][] backupBoard = new int[N][M];
copy(board, backupBoard);
for (int i = 0; i < M; i++) {
drop(i);
go(cnt+1);
copy(backupBoard, board);
}
}
static void drop(int sc) {
int sr = 0;
// 제일 상위에 있는 벽돌 탐색
while (sr < N && board[sr][sc] == 0) sr++;
if (sr >= N) return;
Queue<Integer> q = new ArrayDeque<>();
q.offer(sr); q.offer(sc);
while (!q.isEmpty()) {
int r = q.poll();
int c = q.poll();
// 해당 벽돌로 인해 제거할 벽돌의 범위 설정
int range = board[r][c];
// 0으로 설정하여 방문한 위치임을 나타낸다
board[r][c] = 0;
for (int i = 0; i < 4; i++) {
int nr = r, nc = c;
for (int j = 1; j < range; j++) {
nr += dx[i];
nc += dy[i];
// 범위를 벗어나면 더 이상 갈 필요없다
if \(nr < 0 \|| nr >= N \|| nc < 0 \|| nc >= M)
break;
// 0이라면 원래 벽돌이 없었거나, 이미 벽돌이 제거된 위치이다
if (board[nr][nc] == 0) continue;
q.offer(nr); q.offer(nc);
}
}
}
// 제거 대상 벽돌 제거 및 재정렬
for (int j = 0; j < M; j++) {
Queue<Integer> tmpq = new ArrayDeque<>();
for (int i = N-1; i >= 0; i--) {
if (board[i][j] == 0) continue;
tmpq.offer(board[i][j]);
board[i][j] = 0;
}
int i = N-1;
while (!tmpq.isEmpty()) board[i--][j] = tmpq.poll();
}
}
public static void main(String[] args) throws Exception {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
int testcase = Integer.parseInt(in.readLine());
for (int tc = 1; tc <= testcase; tc++) {
res = Integer.MAX_VALUE;
StringTokenizer st = new StringTokenizer(in.readLine(), " ");
X = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
N = Integer.parseInt(st.nextToken());
board = new int[N][M];
for (int i = 0; i < N; i++) {
st = new StringTokenizer(in.readLine(), " ");
for (int j = 0; j < M; j++)
board[i][j] = Integer.parseInt(st.nextToken());
}
go(0);
System.out.println("#" + tc + " " + res);
}
}
}