반응형
[광고 누르면 오늘의 행운 상승!!]
https://www.acmicpc.net/problem/14502
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 |