From 60d27cf61fde0114cbbfee72e81030a9c0becfd0 Mon Sep 17 00:00:00 2001 From: yukyeongmin <75004920+yukyeongmin@users.noreply.github.com> Date: Wed, 17 Nov 2021 23:23:26 +0900 Subject: [PATCH] =?UTF-8?q?[=EC=9C=A0=EA=B2=BD=EB=AF=BC]=20=EC=97=B0?= =?UTF-8?q?=EA=B5=AC=EC=86=8C3=20(=EC=84=B1=EA=B3=B5)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 문제이해가 가장 중요하다는걸 배워갑니다 --- .../ykm.java" | 87 +++++++++---------- 1 file changed, 39 insertions(+), 48 deletions(-) diff --git "a/solution/BOJ_17142_\354\227\260\352\265\254\354\206\214-3/ykm.java" "b/solution/BOJ_17142_\354\227\260\352\265\254\354\206\214-3/ykm.java" index 61de39e..9851df6 100644 --- "a/solution/BOJ_17142_\354\227\260\352\265\254\354\206\214-3/ykm.java" +++ "b/solution/BOJ_17142_\354\227\260\352\265\254\354\206\214-3/ykm.java" @@ -3,7 +3,7 @@ import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; -import java.util.PriorityQueue; +import java.util.LinkedList; import java.util.Queue; import java.util.StringTokenizer; @@ -30,22 +30,6 @@ public virus(int x, int y, boolean active, int count) { this.count = count; } - public boolean isActive() { - return active; - } - - public void setActive(boolean active) { - this.active = active; - } - - public int getCount() { - return count; - } - - public void setCount(int count) { - this.count = count; - } - @Override public int compareTo(Main.virus o) { return this.count - o.count; @@ -55,6 +39,7 @@ public int compareTo(Main.virus o) { static int N; // 연구소의 크기 static int M; // 바이러스 개수 static int[][] Map; // 0: 빈칸, 1:벽, 2:바이러스(비활성), 3:바이러스(활성) + static boolean[][] isVirus; static ArrayList v = new ArrayList(); @@ -64,16 +49,14 @@ public int compareTo(Main.virus o) { static int area; public static void main(String[] args) throws IOException { - System.setIn(new FileInputStream("input.txt")); 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][N]; - area = N * N; // 바이러스가 갈수있는 공간의 넓이 = 연구소에서 벽을 제외한 공간의 넓이 - answer = N * N; + area = N * N; // 바이러스가 갈수있는 공간의 넓이 = 연구소에서 벽과 바이러스 제외한 공간의 넓이 + answer = N * N; // 걸리는 최종 시간 for (int i = 0; i < N; i++) { st = new StringTokenizer(br.readLine()); @@ -83,11 +66,16 @@ public static void main(String[] args) throws IOException { area--; else if (Map[i][j] == 2) { v.add(new virus(i, j)); + area--; } } } - activate(-1, 0); + if (area == 0) + answer = 0; + else + activate(-1, 0); // 바이러스가 퍼져야하는 공간이 있을때만 활성화 시키기 + if (answer == N * N) System.out.println(-1); else @@ -99,20 +87,17 @@ else if (Map[i][j] == 2) { // DFS로 활성화 시킬 바이러스 고르기 public static void activate(int index, int count) { if (count == M) { // 활성화가 끝나면 퍼뜨려봐야 함. - int turn = spread(); - if (turn > 0) { - answer = Math.min(turn, answer); - } + answer = Math.min(spread(), answer); return; } else { // 활성화 시킬 M개의 바이러스 고르기 for (int i = index + 1; i < v.size(); i++) { virus current = v.get(i); - current.setActive(true); - current.setCount(0); + current.active = true; + current.count = 0; activate(i, count + 1); - current.setActive(false); - current.setCount(-1); + current.active = false; + current.count = -1; } } } @@ -121,26 +106,23 @@ public static void activate(int index, int count) { // 가능한 경우 -> 퍼뜨리는데 걸린 시간 // BFS로 퍼뜨리기 public static int spread() { - boolean[][] isVisited = new boolean[N][N]; + isVirus = new boolean[N][N]; + int countVirus = 0; + int turn = 0; + Queue q = new LinkedList(); + // pq는 메모리 효율이 좋지만 정렬때문에 느림 - Queue q = new PriorityQueue(); - for (int i = 0; i < v.size(); i++) { + for (int i = 0; i < v.size(); i++) { // 전체 바이러스중 활성화 된 바이러스만 q에 넣기 virus current = v.get(i); - if (current.isActive()) { + if (current.active) { + isVirus[current.x][current.y] = true; // 바이러스가 이미 퍼졌음을 표시 q.add(current); } } - int countVirus = 0; - int turn = 0; while (!q.isEmpty()) { virus current = q.poll(); - isVisited[current.x][current.y] = true; - countVirus++; - turn = current.getCount(); - - if (countVirus == area) - return turn; + int t = current.count; for (int i = 0; i < 4; i++) { int nextX = current.x + mx[i]; @@ -151,16 +133,25 @@ public static int spread() { continue; // 벽으로는 바이러스가 퍼질수 없음. // 이미 바이러스가 퍼진곳 제외 - if (Map[nextX][nextY] == 1 || isVisited[nextX][nextY]) + if (Map[nextX][nextY] == 1 || isVirus[nextX][nextY]) continue; - else { - isVisited[nextX][nextY] = true; - q.add(new virus(nextX, nextY, true, turn + 1)); + // 비활성화 바이러스를 만난 경우 + if (Map[nextX][nextY] == 2) { + isVirus[nextX][nextY] = true; + q.add(new virus(nextX, nextY, true, t + 1)); + } else if (Map[nextX][nextY] == 0) { + isVirus[nextX][nextY] = true; + countVirus++; + q.add(new virus(nextX, nextY, true, t + 1)); + turn = Math.max(turn, t + 1); } } - } - return 0; + + if (countVirus == area) + return turn; + else + return N * N; } }