diff --git "a/java/src/jan/week2/boj/\353\262\275\355\203\200\352\270\260_\354\235\264\353\213\244\354\230\210.java" "b/java/src/jan/week2/boj/\353\262\275\355\203\200\352\270\260_\354\235\264\353\213\244\354\230\210.java" new file mode 100644 index 0000000..c9c7a88 --- /dev/null +++ "b/java/src/jan/week2/boj/\353\262\275\355\203\200\352\270\260_\354\235\264\353\213\244\354\230\210.java" @@ -0,0 +1,117 @@ +package jan.week2.boj; + +import java.io.*; +import java.util.*; + +// Deque 문제 +// 그냥 Queue로 하면 안됨 .. Queue는 모든 간선 비용이 동일할떄 +// 근데 이 문제는 간선이 0 or 1임 +public class 벽타기_이다예 { + + static BufferedReader br; + static StringTokenizer st; + static int H,W; + + // 지도 정보 ( #, ., S,E ) + static int[][] map; + // 최단거리만 DP + static int[][] dist; + // 주변에 벽이 있는지 + static boolean[][] wallMap; + + // 이동 ( 동 남 서 북 ) + static int[] dx = {1,0,-1,0}; + static int[] dy = {0,-1,0,1}; + + public static void main(String[] args) throws IOException { + final int INF =1_000_000_000; + + br = new BufferedReader(new InputStreamReader(System.in)); + st = new StringTokenizer(br.readLine()); + H = Integer.parseInt(st.nextToken()); + W = Integer.parseInt(st.nextToken()); + map = new int[H][W]; + dist = new int[H][W]; + wallMap = new boolean[H][W]; + // 시작점 + int startRow = 0; + int startCol = 0; + // 도착점 + int endRow = 0; + int endCol = 0; + + // 지도 정보 저장 and 시작점 도착점 찾기 and dist에 최댓값저장 + for (int i = 0; i < H ; i++){ + String line = br.readLine(); + for (int j = 0; j < W ; j++){ + char now = line.charAt(j); + map[i][j] = now; + dist[i][j] = INF; + if (now == 'S') { + startRow = i; + startCol = j; + } + if (now == 'E'){ + endRow = i; + endCol = j; + } + } + } + + // 주변에 벽이 있는지 정보 저장 + for (int r = 0; r < H ; r ++){ + for (int c = 0; c < W ; c++){ + for (int d = 0; d < 4 ; d++){ + int ny = r + dy[d]; + int nx = c + dx[d]; + + if (nx < 0 || nx >= W || ny < 0 || ny >= H) continue; + if (map[ny][nx] == '#') wallMap[r][c] = true; + } + } + } + + int result = bfs(startRow,startCol,endRow,endCol); + + System.out.println(result); + + } + + + static int bfs(int startRow,int startCol,int endRow,int endCol) { + Deque dq = new ArrayDeque<>(); + + dq.addFirst(new int[]{startRow, startCol}); + dist[startRow][startCol] = 0; + + while (dq.size() != 0) { + int[] now = dq.pollFirst(); + + int nowR = now[0]; + int nowC = now[1]; + + if (nowR == endRow && nowC == endCol) return dist[nowR][nowC]; + + for (int d = 0; d < 4; d++) { + int ny = nowR + dy[d]; + int nx = nowC + dx[d]; + + // 가려고 하는 칸이 맵 인덱스를 벗어났을 경우 또는 벽일 경우 못감 + if (ny < 0 || ny >= H || nx < 0 || nx >= W || (map[ny][nx] == '#')) continue; + + // 지금 칸도 벽 인접 칸이고 다음 칸도 벽 인접 칸일경우는 이동 시간 +1 안해도됨 + // 하나라도 인접칸이 아닐 시 이동 시간 +1 + int near = (wallMap[ny][nx] && wallMap[nowR][nowC]) ? 0 : 1; + int nd = dist[nowR][nowC] + near; + + if (nd < dist[ny][nx]) { + dist[ny][nx] = nd; + if (near == 0) dq.addFirst(new int[]{ny, nx}); + else dq.addLast(new int[]{ny, nx}); + } + } + + } + return dist[endRow][endCol]; + } +} diff --git "a/java/src/jan/week2/boj/\353\262\275\355\203\200\352\270\260_\354\235\264\353\213\244\354\230\210_\355\213\200\353\246\260\355\222\200\354\235\264.java" "b/java/src/jan/week2/boj/\353\262\275\355\203\200\352\270\260_\354\235\264\353\213\244\354\230\210_\355\213\200\353\246\260\355\222\200\354\235\264.java" new file mode 100644 index 0000000..6cab68b --- /dev/null +++ "b/java/src/jan/week2/boj/\353\262\275\355\203\200\352\270\260_\354\235\264\353\213\244\354\230\210_\355\213\200\353\246\260\355\222\200\354\235\264.java" @@ -0,0 +1,129 @@ +package jan.week2.boj; + +import java.io.*; +import java.util.*; + +public class 벽타기_이다예_틀린풀이 { + + static BufferedReader br; + static StringTokenizer st; + // H : 행 // W : 열 + static int H; + static int W; + + // 지도 + static char[][] map; + // dp 지도 + static int[][] dp; + // 주변 war이 있는지 확인하는 지도 + static boolean[][] mapWar; + + // 시작점 + static int startRow; + static int startCol; + + // 도착점 + static int endRow; + static int endCol; + + // 일반 이동 ( 동, 남, 서, 북) + static int[] dx = {1, 0, -1, 0}; + static int[] dy = {0, -1, 0 ,1}; + + // 결과값 + static int result; + + public static void main(String[] args) throws IOException { + br = new BufferedReader(new InputStreamReader(System.in)); + st = new StringTokenizer(br.readLine()); + + H = Integer.parseInt(st.nextToken()); + W = Integer.parseInt(st.nextToken()); + + map = new char[H][W]; + dp = new int[H][W]; + mapWar = new boolean[H][W]; + + result = Integer.MAX_VALUE; + + // 지도에 벽이랑 이제 빈칸 주입 + for(int i = 0; i < H; i++){ + String line = br.readLine(); + for (int j =0; j < W ; j++){ + map[i][j] = line.charAt(j); + // for문 도는김에 dp에 최댓값들 넣기 + dp[i][j] = Integer.MAX_VALUE; + } + } + + + // 시작 점 찾기 + for (int i = 0 ; i < H; i++){ + for (int j = 0 ; j < W ; j++){ + if (map[i][j] == 'S'){ + startRow = i; + startCol = j; + } + } + } + + // 끝 점 찾기 + for (int i = 0 ; i < H ; i++){ + for (int j = 0; j < W ; j++){ + if (map[i][j] == 'E'){ + endRow = i; + endCol = j; + } + } + } + + // 벽 있는지 체크 + for ( int i = 0 ; i < H ; i++){ + for ( int j = 0 ; j < W ; j++){ + for (int k = 0 ; k < 4 ; k++){ + int nx = i + dx[k]; + int ny = j + dy[k]; + + if (nx < 0 || nx >= W || ny < 0 || ny >= H || (mapWar[i][j]) ) continue; + // #은 벽 + if (map[ny][nx] =='#') mapWar[i][j] = true; + } + } + } + + dp(startRow, startCol,0); + + System.out.println(result); + } + + // # = 벽 , . = 빈칸 + static void dp(int nowRow, int nowCol, int move){ + + // 현재 있는 위치가 이제 도착점이면 result 확인 + if (nowRow == endRow && nowCol == endCol){ + if (move < result) result = move; + return; + } + + // 지금 이동횟수가 dp 맵 해당 칸에서의 이동횟수보다 크면 최소시간을 출력하는것에 어긋나니까 해당 루트는 더 계산할 필요가 없음 + if (dp[nowRow][nowCol] <= move) return; + + dp[nowRow][nowCol] = move; + + + // 이제 이동 + // 벽이 있는지 체크 + for (int i = 0; i < 4 ; i++){ + int nx = nowCol + dx[i]; + int ny = nowRow + dy[i]; + if ( nx < 0 || nx >= W || ny < 0 || ny >= H ) continue; + + // 이동한 칸이 빈칸 일때만 이동 + if (!(map[ny][nx] == '#')){ + if (mapWar[nowRow][nowCol] && mapWar[ny][nx]) dp(ny,nx,move); + else dp(ny,nx,move + 1); + } + } + }; + +}