Algorithm/BOJ
[BOJ] 연구소 2
goakgoak
2020. 2. 8. 21:51
[17141] 연구소2
https://www.acmicpc.net/problem/17141
- 바이러스를 놓을 수 있는 칸(arr[i][j] = 2)에 주어진 M개의 바이러를 놓았을 때 모든 빈 칸(arr[i][j] = 0)에 바이러스를 퍼뜨리는 최소 시간을 구하는 문제
- 0은 빈 칸, 1은 벽, 2는 바이러스를 놓을 수 있는 칸이다.
- 바이러스를 어떻게 놓아도 모든 빈 칸에 바이러스를 퍼뜨릴 수 없는 경우에는 -1을 출력한다.
Solution
- permutation()을 사용한 BFS 문제
- 바이러스를 놓을 수 있는 칸의 좌표를 리스트에 모두 담고, permutation() 함수를 돌려 M개의 좌표를 뽑은 후에 BFS로 바이러스를 퍼뜨린다.
소스코드
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Scanner;
import java.util.StringTokenizer;
public class Main {
static int n, m, min;
static int[] a;
static int[] dx = { 1, -1, 0, 0 };
static int[] dy = { 0, 0, 1, -1 };
static int[][] origin, copy, visited;
static List<Node> virus;
static Queue<Node> q;
static class Node {
int x, y;
public Node(int x, int y) {
this.x = x;
this.y = y;
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
StringTokenizer st = new StringTokenizer(sc.nextLine());
n = stoi(st.nextToken());
m = stoi(st.nextToken());
origin = new int[n][n];
copy = new int[n][n];
virus = new ArrayList<>();
a = new int[m];
int zero = 0;
int count = 0;
for (int i = 0; i < n; i++) {
st = new StringTokenizer(sc.nextLine());
for (int j = 0; j < n; j++) {
origin[i][j] = stoi(st.nextToken());
if (origin[i][j] == 0) {
zero++;
}
if (origin[i][j] == 2) {
virus.add(new Node(i, j));
origin[i][j] = 0;
count++;
}
}
}
min = Integer.MAX_VALUE;
permutation(0, 0, count);
if(min == Integer.MAX_VALUE)
min = -1;
if(zero == 0 && count == m)
min = 0;
System.out.println(min);
}
public static void simulation() {
copy();
for (int i : a) {
Node node = virus.get(i);
q.offer(node);
visited[node.x][node.y] = 1;
}
bfs();
//print();
int result = calc();
if(result > -1) min = Math.min(min, result);
}
public static int calc() {
int zero = 0;
int result = -1;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (copy[i][j] == 0)
zero++;
result = Math.max(result, copy[i][j]);
}
}
if (zero > m)
return -1;
return result;
}
public static void bfs() {
while (!q.isEmpty()) {
Node cur = q.poll();
for (int i = 0; i < 4; i++) {
int nx = cur.x + dx[i];
int ny = cur.y + dy[i];
if (nx < 0 || ny < 0 || nx >= n || ny >= n)
continue;
if (copy[nx][ny] == 1 || visited[nx][ny] == 1)
continue;
copy[nx][ny] = copy[cur.x][cur.y] + 1;
q.offer(new Node(nx, ny));
visited[nx][ny] = 1;
}
}
}
public static void permutation(int depth, int start, int count) {
if (depth == m) {
init();
simulation();
return;
}
for (int i = start; i < count; i++) {
a[depth] = i;
permutation(depth + 1, i + 1, count);
}
}
public static void copy() {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
copy[i][j] = origin[i][j];
}
}
}
public static void init() {
visited = new int[n][n];
q = new LinkedList<>();
}
public static int stoi(String s) {
return Integer.parseInt(s);
}
}