반응형
[광고 누르면 오늘의 행운 상승!!]
https://www.acmicpc.net/problem/14502
14502번: 연구소
인체에 치명적인 바이러스를 연구하던 연구소에서 바이러스가 유출되었다. 다행히 바이러스는 아직 퍼지지 않았고, 바이러스의 확산을 막기 위해서 연구소에 벽을 세우려고 한다. 연구소는 크기가 N×M인 직사각형으로 나타낼 수 있으며, 직사각형은 1×1 크기의 정사각형으로 나누어져 있다. 연구소는 빈 칸, 벽으로 이루어져 있으며, 벽은 칸 하나를 가득 차지한다. 일부 칸은 바이러스가 존재하며, 이 바이러스는 상하좌우로 인접한 빈 칸으로 모두 퍼져나갈 수 있다.
www.acmicpc.net
BFS + 조합 문제
1. 리스트에 안전구역의 row , col 좌표를 담는다.
2. 조합으로 0~ 안전구역수까지의 숫자를 구한다.
3. 조합으로 구해진 3개의 구역을 VISIT 처리한다. (MAP을 변경하지 않는다) - 사실 큰 시간 차이는 없었다.
4. BFS를 시작한다. 이때 전염된 수만큼을 반환한다.
5. 안전구역수 - 전염구역 - 벽 3개 를 계산하여 경우의 수당 최대의 안전구역 수를 저장한다.
6. 끝
package Study0307;
import java.io.*;
import java.util.*;
class Pos{
int row, col;
public Pos(int row, int col) {
this.row = row;
this.col = col;
}
}
public class 연구소 {
public static final int[] dx = {1,0,-1,0};
public static final int[] dy = {0,1,0,-1};
public static int N,M,ans,safeZone,max = Integer.MIN_VALUE;;
public static boolean[][] visit;
public static boolean[] v;
public static int[][] map;
public static int arr[];
public static int num[];
public static ArrayList<Pos> list;
public static ArrayList<Pos> virusList;
public static Queue<Pos> q;
public static void main(String[] args) throws Exception {
System.setIn(new FileInputStream("test.txt"));
Scanner sc = new Scanner(System.in);
N = sc.nextInt();
M = sc.nextInt();
map = new int[N][M];
list = new ArrayList<>();
virusList = new ArrayList<>();
q = new LinkedList<>();
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
map[i][j] = sc.nextInt();
if(map[i][j] == 0) list.add(new Pos(i,j));
if(map[i][j] == 2) virusList.add(new Pos(i,j));
}
}
safeZone = list.size();
arr = new int[3];
num = new int[safeZone];
v = new boolean[safeZone];
for (int i = 0; i < safeZone; i++) num[i] = i;
permutation(0);
System.out.println(max);
}
public static void permutation(int cnt) {
if(cnt == 3) {
//조합으로 만든 3가지 숫자
visit = new boolean[N][M];
for (int i = 0; i < 3; i++) {
//map을 변경하지 않고 visit배열을 true로 바꾸어서 처리한다.
visit[list.get(arr[i]).row][list.get(arr[i]).col] = true;
}
//안전구역 - 전염된 갯수 - 벽3개 = case N 의 결과값
max = Math.max(max, safeZone - bfs() -3);
return;
}
for (int i = 0; i < list.size(); i++) {
if(!v[i]) {
v[i] = true;
arr[cnt] = num[i];
permutation(cnt + 1);
v[i] = false;
}
}
}
public static int bfs() {
//바이러스를 q에 넣는다.
for (Pos v : virusList) q.add(v);
int cnt = 0;
while(!q.isEmpty()) {
Pos virus = q.poll();
for (int i = 0; i < 4; i++) {
int nx = virus.row + dx[i];
int ny = virus.col + dy[i];
if(nx < 0 || nx >= N || ny < 0 || ny >= M){
continue;
}
if(map[nx][ny] == 1 || map[nx][ny] == 2 || visit[nx][ny]) {
continue;
}
visit[nx][ny] = true;
//전염 증가
cnt++;
q.add(new Pos(nx,ny));
}
}
//전염된 만큼의 cnt 를 반환
return cnt;
}
}
시간을 줄이기 위하여 여러가지 방법을 시도했으나 결국 다 비슷비슷한 시간이 나온다.
다른 사람의 코드를 보면 더 빠른데, 조합을 구하기 위하여 재귀 함수를 쓰지 않고 3중 FOR문으로 해결하였다.
함수 호출에 걸리는 시간의 차이인지 다른 차이인지 더 공부해야할 것 같다.
반응형
'2. 알고리즘사이트 > 1. 백준' 카테고리의 다른 글
2048(Easy) [백준 12100][골드 2][Java] (0) | 2020.03.08 |
---|---|
퇴사 [백준 14501][실버4][Java] (0) | 2020.03.07 |
계란으로 계란치기 [백준 16987][실버3][Java] (1) | 2020.03.06 |
테트로미노 [백준 14500][골드5][Java] (0) | 2020.03.06 |
문자판 [백준 2186][골드3][Java] (0) | 2020.03.05 |