티스토리 뷰
[백준 2206번 벽 부수고 이동하기 URL]
https://www.acmicpc.net/problem/2206
[비슷한 유형의 문제]
2019/02/14 - [알고리즘 문제/백준(BOJ)] - [백준 1194번] 달이 차오른다, 가자.
이 문제를 풀기위해서 고려해야할 사항은 다음과 같습니다.
1. 벽을 한번도 부수지 않고 이동하는 경우와 벽을 한번 부수고 이동하는 경로를 따로 체크해야합니다.
2. 2차원 배열 visited가 아닌 3차원 배열 visited[2][row][col]을 선언하여 벽을 부수지 않고 이동하는 경우는
visited[0][row][col]에 방문체크를 하고 벽 하나를 부수고 이동하는 경우에는 visited[1][row][col]에 방문체크를
해줍니다.
3. Node 클래스의 jump 멤버가 벽을 부수고 온 경우인지 아닌지 판별하는 변수입니다.
4. 이전에 벽을 부수지 않은 경우(jump == 0)는 2가지로 나뉩니다.
1) 벽을 만났을 경우
벽을 만났을 경우에는 이전에 벽을 부수지 않았으므로 해당 벽을 부수고 이동합니다. (jump를 1로 바꿈)
2) 벽을 만나지 않았을 경우
벽을 만나지 않았을 경우에는, 그대로 방문처리를 해주고 탐색을 계속합니다.
5. 이전에 벽을 부순 경우(jump == 1)또한 2가지로 나뉩니다.
1) 벽을 만났을 경우
이미 벽을 한번 부쉈으므로 해당 벽을 부술 수 없기 때문에 탐색을 해당 지점에서 종료합니다.
2) 벽을 만나지 않았을 경우
벽을 만나지 않았을 경우에는, 그대로 방문처리를 해주고 탐색을 계속합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.LinkedList; import java.util.Queue; import java.util.StringTokenizer; public class Main { public static int N, M, ans = Integer.MAX_VALUE; public static int[] dirX = new int[] { 0, 0, -1, 1 }; public static int[] dirY = new int[] { -1, 1, 0, 0 }; public static int[][] map; public static boolean[][][] visited; public static void main(String[] args) throws Exception { 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][M]; visited = new boolean[2][N][M]; for (int i = 0; i < N; i++) { String str = br.readLine(); for (int j = 0; j < M; j++) { map[i][j] = Integer.parseInt(str.charAt(j) + ""); } } solve(); if(ans == Integer.MAX_VALUE) System.out.println(-1); else System.out.println(ans); } public static void solve() { Queue<Node> q = new LinkedList<Node>(); q.offer(new Node(0, 0, 1, 0)); while (!q.isEmpty()) { Node node = q.poll(); int row = node.row; int col = node.col; int cnt = node.cnt; int jump = node.jump; if (row == N - 1 && col == M - 1) { ans = Math.min(ans, cnt); continue; } for (int i = 0; i < 4; i++) { int nr = row + dirX[i]; int nc = col + dirY[i]; if (isBoundary(nr, nc)) { if (jump == 1) { if (!visited[jump][nr][nc] && map[nr][nc] == 0) { visited[jump][nr][nc] = true; q.offer(new Node(nr, nc, cnt + 1, jump)); } } else { // 벽을 안부순 상태 if (map[nr][nc] == 1) { if (!visited[jump + 1][nr][nc]) { visited[jump + 1][nr][nc] = true; q.offer(new Node(nr, nc, cnt + 1, jump + 1)); } } else if (map[nr][nc] == 0) { if (!visited[jump][nr][nc]) { visited[jump][nr][nc] = true; q.offer(new Node(nr, nc, cnt + 1, jump)); } } } } } } } public static boolean isBoundary(int row, int col) { return (row >= 0 && row < N) && (col >= 0 && col < M); } } class Node { int row; int col; int cnt; int jump; public Node(int row, int col, int cnt, int jump) { super(); this.row = row; this.col = col; this.cnt = cnt; this.jump = jump; } } | cs |
'알고리즘 문제 > 백준(BOJ)' 카테고리의 다른 글
[백준 2583번] 영역 구하기_C++ (0) | 2019.02.17 |
---|---|
[백준 1012번] 유기농 배추 (C, C++) (0) | 2019.02.17 |
[백준 1194번] 달이 차오른다, 가자._JAVA (1) | 2019.02.14 |
[백준 11559번] Puyo Puyo (Java) (0) | 2019.02.12 |
[백준 2234번] 성곽 (Java, C++) (0) | 2019.02.12 |
- Total
- Today
- Yesterday
- 최소힙
- BFS
- 트리
- 시뮬레이션
- 정렬
- 백준
- 자바
- 알고리즘
- 연산자 끼워넣기
- 브루트포스
- 최대힙
- 리스트
- 힙정렬
- 탐색
- 배열
- 구현
- 힙
- 구슬 탈출2
- 큐
- 중간값
- 나무 재테크
- SWEA
- DFS
- 삼성
- 우선순위 큐
- 영역 구하기
- 탈주범 검거
- 14888
- 알고스팟
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |