BOJ_14502_연구소
2021. 9. 29. 13:46ㆍ백준 알고리즘(BOJ)
1
구분: 그래프 이론, 그래프 탐색, 부르트포스 알고리즘, 너비 우선 탐색
언어: Java
전략:
1. 벽을 세울 빈칸 3개를 조합을 이용해서 선택한다.
- 벽은 3개만 세울 수 있으니까 3개만 만듬
- 빈칸들 중 3개를 선택한다.
2. 조합이 완성되면 그 곳에 벽을 세우고, 바이러스를 퍼트린다.
- BFS를 이용하여 전체를 다 탐색하면서 바이러스를 퍼트린다.
3. 안전 영역의 넓이를 구한다.
- 바이러스가 퍼지지 않은 부분(0)의 면적(개수)을 구한다.
2. 코드
import java.util.ArrayList;
import java.util.Scanner;
import java.util.Queue;
import java.util.LinkedList;
public class Main {
static int w, h;//가로, 세로
static int[][] map, mapcopy;//맵과 맵 복사본
static ArrayList<Node> walls, virus;//벽과 바이러스를 담을 에레이리스트
static int[] comb;//조합을 담을 배열
//4방 탐색
static int[] dx = {1, -1, 0, 0};
static int[] dy = {0, 0, 1, -1};
static int maxarea = Integer.MIN_VALUE;
//좌표를 담을 자료구조
static class Node{
int y, x;
Node(int y, int x){
this.x = x;
this.y = y;
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
h = scanner.nextInt();
w = scanner.nextInt();
walls = new ArrayList<>();
virus = new ArrayList<>();
comb = new int[3];//벽은 딱 3개
map = new int[h][w];
for(int i = 0; i<h; i++) {
for(int j = 0; j<w; j++) {
map[i][j] = scanner.nextInt();
if(map[i][j]==0) {//벽이라면 벽에 넣는다.
walls.add(new Node(i, j));
}
else if(map[i][j] == 2) {//바이러스라면 바이러스에 넣는다.
virus.add(new Node(i, j));
}
}
}
combination(0,0);
System.out.println(maxarea);
}//main
//벽을 세울 위치 조합 만드는 함수
private static void combination(int cnt, int start) {
if(cnt ==3) {
spreadVirus();
int nowarea = safeArea(mapcopy);
//최대 면적 고른다.
maxarea = Math.max(maxarea, nowarea);
return;
}
//조합을 생성하는 중
for(int i = start; i<walls.size(); i++) {
comb[cnt] = i;
combination(cnt+1, i+1);
}
}//combination
//바이러스의 퍼짐을 구하는 함수
private static void spreadVirus() {
//원본 지도를 복제한다(원래는 계속 사용해야 하기 떄문에)
mapcopy = new int[h][w];
for(int i = 0; i<h; i++) {
for(int j = 0; j<w; j++) {
mapcopy[i][j] = map[i][j];
}
}
//벽 세우기
for(int i = 0; i<3; i++) {
Node node = walls.get(comb[i]);
mapcopy[node.y][node.x] = 1;
}
//바이러스 퍼트리기
Queue<Node> q = new LinkedList<>();
for(int i = 0; i<virus.size(); i++) {
Node node = virus.get(i);
q.add(node);
}
while(!q.isEmpty()) {
Node node = q.poll();
int qx = node.x;
int qy = node.y;
for(int d = 0; d<4; d++) {
int nx = qx + dx[d];
int ny = qy + dy[d];
//범위 탐색
if(nx<0||ny<0||nx>=w||ny>=h)
continue;
//벽이거나 이미 바이러스면 지나가
if(mapcopy[ny][nx]!=0)
continue;
//빈칸을 바이러스로 만들어
mapcopy[ny][nx] = 2;
q.add(new Node(ny, nx));
}
}
}//virus
//안전 영역을 구하는 함수
private static int safeArea(int[][] arr) {
int area = 0;
for(int i = 0; i<h; i++) {
for(int j = 0; j<w; j++) {
//바이러스가 안퍼진 공간들을 다 더한다.
if(arr[i][j] == 0) {
area++;
}
}
}
return area;
}//safearea
}
3
부르트포스와 BFS를 동시에 접할 수 있는 좋은 문제다.
예전에 시도했을떄는 풀지 못하였는데, 이제는 풀 수 있어서 기분이 좋다.
'백준 알고리즘(BOJ)' 카테고리의 다른 글
BOJ_20056_마법사 상어와 파이어볼 (0) | 2021.10.23 |
---|---|
BOJ_17144_미세먼지 안녕! (0) | 2021.10.21 |
BOJ_10972_다음 순열 (0) | 2021.09.28 |
BOJ_12865_평범한 배낭 (0) | 2021.09.27 |
BOJ_17472_다리 만들기2 (0) | 2021.09.24 |