섞어서 푸는건 보통 DFS로 경우의 수를 구하고 BFS로 탐색하는 편이다.
https://www.acmicpc.net/problem/14502
비슷한 문제: https://www.acmicpc.net/problem/18428
- DFS로 벽 세우는 경우의 수 구하기
- 다음 BFS로 탐색하는 두가지 경우가 있는데
- 2중 for문을 돌면서 map[i][j]가 2일경우 Queue에 담아 탐색을 시작하는경우
- map[i][j]가 2인 경우만 Queue에 담아서 진행하는 경우이다.
import java.util.*;
import java.io.*;
public class Main {
static int map[][];
static int tmp[][];
static int N;
static int M;
static int move_x[] = {1, -1, 0, 0};
static int move_y[] = {0, 0, 1, -1};
static ArrayList<Integer> answer = new ArrayList<>();
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
map = new int[N][M];
tmp = new int[N][M];
for(int n = 0; n < N; n++) {
st = new StringTokenizer(br.readLine(), " ");
for(int m = 0; m < M; m++)
map[n][m] = Integer.parseInt(st.nextToken());
}
dfs(0);
System.out.println(Collections.max(answer));
}
public static void dfs(int count) {
if(count == 3) {
for(int i = 0; i < N; i++) {
for(int j = 0; j < M; j++)
tmp[i][j] = map[i][j];
}
int result = bfs();
answer.add(result);
return;
}
for(int i = 0; i < N; i++) {
for(int j = 0; j < M; j++) {
if(map[i][j] == 0) {
map[i][j] = 1;
count += 1;
dfs(count);
map[i][j] = 0;
count -= 1;
}
}
}
}
public static int bfs() {
Queue<Integer> QX = new LinkedList<>();
Queue<Integer> QY = new LinkedList<>();
//2. bfs를 돌면서 바이러스를 퍼트려준다.
for(int i = 0; i < N; i++) {
for(int j = 0; j < M; j++) {
if(tmp[i][j] == 2) {
QX.add(i);
QY.add(j);
}
while(!QX.isEmpty()) {
int X = QX.poll();
int Y = QY.poll();
for(int mx = 0; mx < move_x.length; mx++) {
int go_x = X + move_x[mx];
int go_y = Y + move_y[mx];
if(go_x >= 0 && go_y >= 0 && go_x < N && go_y < M) {
if(tmp[go_x][go_y] == 0) {
QX.add(go_x);
QY.add(go_y);
tmp[go_x][go_y] = 2;
}
}
}
}
}
}
int result = 0;
//3. 돌면서 빈칸의 개수를 count해준다.
for(int i = 0; i < N; i++) {
for(int j = 0; j < M; j++) {
if(tmp[i][j] == 0)
result++;
}
}
return result;
}
}
import java.util.*;
import java.io.*;
public class Main {
static int N;
static int M;
static int map[][];
static int[] moveX = {1, -1, 0, 0};
static int[] moveY = {0, 0, 1, -1};
static int answer;
static ArrayList<Node> virus = new ArrayList<>();
public static class Node{
int x;
int y;
public Node(int x, int y) {
this.x = x;
this.y = y;
}
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
map = new int[N][M];
answer = 0;
for(int i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine(), " ");
for(int j = 0; j < M; j++) {
map[i][j] = Integer.parseInt(st.nextToken());
if(map[i][j] == 2) {
virus.add(new Node(i, j));
}
}
}
dfs(0);
System.out.println(answer);
}
public static void dfs(int count) {
if(count == 3) {
bfs();
return;
}
for(int i = 0; i < N; i++) {
for(int j = 0; j < M; j++) {
if(map[i][j] == 0) {
map[i][j] = 1;
dfs(count+1);
map[i][j] = 0;
}
}
}
}
public static void bfs() {
boolean check[][] = new boolean[N][M];
int copyMap[][] = new int[N][M];
Queue<Node> q = new LinkedList<>();
// 1. 배열 복사
for(int i = 0; i < N; i++) {
for(int j = 0; j < M; j++) {
copyMap[i][j] = map[i][j];
}
}
for(Node node : virus) {
q.add(node);
check[node.x][node.y] = true;
}
while(!q.isEmpty()) {
Node node = q.poll();
int x = node.x;
int y = node.y;
for(int i = 0; i < 4; i++) {
int goX = x + moveX[i];
int goY = y + moveY[i];
if(goX < 0 || goY < 0 || goX >= N || goY >= M)
continue;
if(copyMap[goX][goY] != 0 || check[goX][goY])
continue;
check[goX][goY] = true;
copyMap[goX][goY] = 2;
q.add(new Node(goX, goY));
}
}
int count = 0;
for(int i = 0; i < N; i++) {
for(int j = 0; j < M; j++) {
if(copyMap[i][j] == 0)
count++;
}
}
answer = Math.max(answer, count);
}
}