-
Notifications
You must be signed in to change notification settings - Fork 156
/
solution.java
144 lines (122 loc) · 4.09 KB
/
solution.java
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
import java.io.*;
import java.lang.reflect.Array;
import java.util.*;
public class Main {
static FastReader scan = new FastReader();
static StringBuilder sb = new StringBuilder();
static int N, M, B, ans;
static int[][] A, blank;
static boolean[][] visit;
static int[][] dir = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
static void input() {
N = scan.nextInt();
M = scan.nextInt();
A = new int[N + 1][M + 1];
blank = new int[N * M + 1][2];
visit = new boolean[N + 1][M + 1];
for (int i = 1; i <= N; i++)
for (int j = 1; j <= M; j++)
A[i][j] = scan.nextInt();
}
// 바이러스 퍼뜨리기!!
static void bfs() {
Queue<Integer> Q = new LinkedList<>();
// 모든 바이러스가 시작점으로 가능하니까, 전부 큐에 넣어준다.
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= M; j++) {
visit[i][j] = false;
if (A[i][j] == 2) {
Q.add(i);
Q.add(j);
visit[i][j] = true;
}
}
}
// BFS 과정
while (!Q.isEmpty()) {
int x = Q.poll(), y = Q.poll();
for (int k = 0; k < 4; k++) {
int nx = x + dir[k][0], ny = y + dir[k][1];
if (nx < 1 || ny < 1 || nx > N || ny > M) continue;
if (A[nx][ny] != 0) continue;
if (visit[nx][ny]) continue;
visit[nx][ny] = true;
Q.add(nx);
Q.add(ny);
}
}
// 탐색이 종료된 시점이니, 안전 영역의 넓이를 계산하고, 정답을 갱신한다.
int cnt = 0;
for (int i = 1; i <= N; i++) for (int j = 1; j <= M; j++) if (A[i][j] == 0 && !visit[i][j]) cnt++;
ans = Math.max(ans, cnt);
}
// idx 번째 빈 칸에 벽을 세울 지 말 지 결정해야 하고, 이 전까지 selected_cnt 개의 벽을 세웠다.
static void dfs(int idx, int selected_cnt) {
if (selected_cnt == 3) { // 3 개의 벽을 모두 세운 상태
bfs();
return;
}
if (idx > B) return; // 더 이상 세울 수 있는 벽이 없는 상태
A[blank[idx][0]][blank[idx][1]] = 1;
dfs(idx + 1, selected_cnt + 1);
A[blank[idx][0]][blank[idx][1]] = 0;
dfs(idx + 1, selected_cnt);
}
static void pro() {
// 모든 벽의 위치를 먼저 모아놓자.
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= M; j++) {
if (A[i][j] == 0) {
B++;
blank[B][0] = i;
blank[B][1] = j;
}
}
}
// 벽을 3개 세우는 모든 방법을 확인해보자!
dfs(1, 0);
System.out.println(ans);
}
public static void main(String[] args) {
input();
pro();
}
static class FastReader {
BufferedReader br;
StringTokenizer st;
public FastReader() {
br = new BufferedReader(new InputStreamReader(System.in));
}
public FastReader(String s) throws FileNotFoundException {
br = new BufferedReader(new FileReader(new File(s)));
}
String next() {
while (st == null || !st.hasMoreElements()) {
try {
st = new StringTokenizer(br.readLine());
} catch (IOException e) {
e.printStackTrace();
}
}
return st.nextToken();
}
int nextInt() {
return Integer.parseInt(next());
}
long nextLong() {
return Long.parseLong(next());
}
double nextDouble() {
return Double.parseDouble(next());
}
String nextLine() {
String str = "";
try {
str = br.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return str;
}
}
}