-
[백준 5427] - [BFS 최단거리] - 불 (JAVA)알고리즘/BFS_DFS 2018. 12. 20. 13:57
문제링크 : https://www.acmicpc.net/problem/5427
이 문제는 BFS를 가지고 풀면 되는데 좌표정보를 갖는 queue를 2개를 사용해야 한다.
queue1은 불의 좌표를 저장하는 queue로 사용하고
queue2는 사람의 좌표를 저장하는 queue로 사용한다.
입력 값이 숫자가 아닌 # * . @ 형식의 char 타입 데이터 이기 떄문에 나는 이 char를 custom 해서 int 형의 값으로 변경했다.
- # --> -1
- * --> -2
- . --> 0
- @ --> 1
방문 정보를 저장할 visited 배열을 사용하기 싫어서 빈 공간은 0으로 두고 사람이 움직일때 좌표의 값이 0인 위치만 이동하게 소스를 작성했다.
복잡하다면 char형의 이차원 배열과 visited 배열을 두개 생성하고 문제를 풀면 된다.
초기 필드는 다음과 같이 사용했다.
public static int ROW;
public static int COL;
public static int[][] building; // 빈공간 . => 0 || 벽 # => -1 || 불 * => 1 || 상근이 @ => 2
public static Queue<int[]> queue1; // 불의 좌표를 저장할 큐
public static Queue<int[]> queue2; // 사람의 좌표를 저장할 큐
public static int result; // 지난 시간을 저장할 큐
public static final String RESULT_FAIL = "IMPOSSIBLE";
public static int[] dy = {-1, 1, 0, 0};
public static int[] dx = {0, 0, -1, 1};
그리고 좌표에대한 값을 입력 받을 때의 소스는 다음과 같이 작성했다.
// 좌표입력
for(int i=0; i < ROW; i++) {
String str = br.readLine();
for(int j=0; j < COL; j++) {
building[i][j] = getVal(str.charAt(j));
if(building[i][j] == -2) queue1.offer(new int[] {i, j});
else if(building[i][j] == 1) queue2.offer(new int[] {i, j, 0});
}
}
불에 대한 좌표를 queue1에 저장했고 사람의 좌표를 저장할때는 y, x 좌표에 0을 저장했는데 0의 값은 지난 시간의 정보라 보면 된다.
모든 값을 입력 받았으면 두 큐가 모두 빈 큐가 될때까지 좌표를 상,하,좌,우 로 이동시키면 된다.
소스
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130package dfs_bfs.b_5427;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.util.ArrayList;import java.util.LinkedList;import java.util.List;import java.util.Queue;import java.util.StringTokenizer;public class Main {public static int ROW;public static int COL;public static int[][] building; // 빈공간 . => 0 || 벽 # => -1 || 불 * => 1 || 상근이 @ => 2public static Queue<int[]> queue1; // 불의 좌표를 저장할 큐public static Queue<int[]> queue2; // 사람의 좌표를 저장할 큐public static int result; // 지난 시간을 저장할 큐public static final String RESULT_FAIL = "IMPOSSIBLE";public static int[] dy = {-1, 1, 0, 0};public static int[] dx = {0, 0, -1, 1};public static void main(String[] args) throws IOException{BufferedReader br = new BufferedReader(new InputStreamReader(System.in));StringTokenizer st = null;int testCase = Integer.parseInt(br.readLine());StringBuilder sb = new StringBuilder();while(testCase-- > 0) {st = new StringTokenizer(br.readLine());COL = Integer.parseInt(st.nextToken());ROW = Integer.parseInt(st.nextToken());building = new int[ROW][COL];queue1 = new LinkedList<>();queue2 = new LinkedList<>();result = 0;// 좌표입력for(int i=0; i < ROW; i++) {String str = br.readLine();for(int j=0; j < COL; j++) {building[i][j] = getVal(str.charAt(j));if(building[i][j] == -2) queue1.offer(new int[] {i, j});else if(building[i][j] == 1) queue2.offer(new int[] {i, j, 0});}}bfs();sb.append((result > 0)?result + "\n":RESULT_FAIL+"\n");}System.out.println(sb.toString());}public static void bfs() {while(!queue1.isEmpty() || !queue2.isEmpty()) {int size1 = queue1.size();if(size1 > 0) {while(size1-- > 0) {int y = queue1.peek()[0];int x = queue1.peek()[1];queue1.poll();//불 이동for(int i = 0; i< 4; i++) {int yy = y + dy[i];int xx = x + dx[i];if(yy < 0 || yy >= ROW) continue;if(xx < 0 || xx >= COL) continue;if(building[yy][xx] == -1 || building[yy][xx] == -2) continue; // 벽이거나 이미 불이면 continuebuilding[yy][xx] = -2;queue1.offer(new int[] {yy, xx});}}}// 상근이 이동int size2 = queue2.size();boolean isEnd = false;if(size2 > 0) {while(size2-- > 0) {int y = queue2.peek()[0];int x = queue2.peek()[1];int t = queue2.peek()[2];queue2.poll();for(int i = 0; i < 4; i++) {int yy = y + dy[i];int xx = x + dx[i];if(yy < 0 || yy >= ROW || xx < 0 || xx >= COL) {// 탈출 성공!result = t+1;isEnd = true;break;}if(building[yy][xx] == 0) {building[yy][xx] = t+1;queue2.offer(new int[] {yy, xx, t+1});}}if(isEnd) break;}if(isEnd) break;}else {result = -1;break;}}}public static int getVal(char c) {switch(c) {case '#': return -1;case '*': return -2;case '@': return 1;default: return 0;}}}cs '알고리즘 > BFS_DFS' 카테고리의 다른 글
[백준 2468] - [DFS BFS] - 안전영역 (JAVA) (0) 2018.12.27 [백준 1697] - [bfs] - 숨바꼭질 (0) 2018.12.19 [백준 1012] - [dfs] - 유기농 배추 (JAVA) (0) 2018.12.19 [백준 1260] - [DFS BFS] DFS와 BFS (JAVA) (0) 2018.12.02 [백준-9466]-[DFS]-텀 프로젝트(JAVA) (0) 2018.11.26 댓글