알고리즘/문제풀이
[Java] 백준 14502 : 연구소
abcodef
2022. 4. 10. 22:07
🔗 문제 내용
https://www.acmicpc.net/problem/14502
14502 : 연구소
🌱 문제 풀이 방법
구현 문제! BFS를 잘못 작성해서 문제 찾는데 시간을 잡아먹었다!
🤔 공부가 필요한 부분
없습니다.
💻 코드
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
public class Main{
static int N, M, max;
static int[] list;
static int[][] map;
static int[][] copyMap;
static int[][] move = { { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } };
static boolean[][] visited;
static ArrayList<virus> virusList = new ArrayList<>();
static ArrayList<virus> blankList = new ArrayList<>();
static ArrayList<virus> wallList = new ArrayList<>();
static class virus {
int row;
int col;
public virus(int row, int col) {
super();
this.row = row;
this.col = col;
}
}
public static void main(String args[]) throws Exception {
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];
max = Integer.MIN_VALUE;
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) {
virusList.add(new virus(i, j));
}
if (map[i][j] == 0) {
blankList.add(new virus(i, j));
}
}
}
for (int i = 0; i < 3; i++) {
wallList.add(i, new virus(-1, -1));
}
list = new int[blankList.size()];
for (int i = 0; i < M; i++) { // 조합을 위해서 사용
list[i] = i;
}
subset(0, 0); // 부분집합으로 벽 세우기
System.out.println(max);
}
static void subset(int cnt, int idx) {
if (cnt == 3) {
visited = new boolean[N][M];
copy(); // 복사된 맵 생성
// 벽 세우기
for (int i = 0; i < 3; i++) {
copyMap[wallList.get(i).row][wallList.get(i).col] = 1;
}
// 바이러스 확산
for (int i = 0; i < virusList.size(); i++) {
bfs(virusList.get(i).row, virusList.get(i).col);
}
// 최댓값 갱신
max = Integer.max(max, count());
return;
}
for (int i = idx; i < blankList.size(); i++) {
wallList.set(cnt, blankList.get(i));
subset(cnt + 1, i + 1);
}
}
// 바이러스 확산
static void bfs(int row, int col) {
Queue<virus> queue = new LinkedList<>();
queue.add(new virus(row, col));
copyMap[row][col] = 2;
visited[row][col] = true;
while (!queue.isEmpty()) {
virus pos = queue.poll();
for (int i = 0; i < 4; i++) {
int newRow = pos.row + move[i][0];
int newCol = pos.col + move[i][1];
if (newRow >= N || newCol >= M || newRow < 0 || newCol < 0)
continue;
if (copyMap[newRow][newCol] == 1)
continue;
if (copyMap[newRow][newCol] == 2)
continue;
if (visited[newRow][newCol])
continue;
visited[newRow][newCol] = true;
copyMap[newRow][newCol] = 2;
queue.add(new virus(newRow, newCol));
}
}
}
// 맵 복사
static void copy() {
copyMap = new int[N][M];
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
copyMap[i][j] = map[i][j];
}
}
}
// 안전 지역 카운트
static int count() {
int cnt = 0;
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
if (copyMap[i][j] == 0) {
cnt++;
}
}
}
return cnt;
}
}