문제링크 : https://www.acmicpc.net/problem/2178
문제풀이
bfs로 풀 수 있는 문제이다.
필요한 데이터
- 미로 데이터를 저장할 N x M 크기의 배열
- 칸을 방문했는지 체크하기 위한 N x M 크기의 배열
- 상하좌우 이동을 위한 방향 배열
1) 첫 번째 칸부터 상, 하, 좌, 우로 한 번씩 이동한다.
2) 이동한 위치가 배열의 범위 안에 들면, 이동할 수 있는 칸인지 확인한다.
(값이 1이고, 방문하지 않은 지점이면 이동 가능)
3) 이동할 수 있는 칸이면 이동 횟수 저장 후 큐에 삽입한다.
4) 큐에 있는 요소를 제거한 후, 그 칸부터 다시 상, 하, 좌, 우로 한 번씩 이동한다.
(이하 반복)
따로 Point라는 클래스를 만들어 x, y, 그 칸 까지의 이동 횟수를 저장해놓았는데,
다른 블로그 글을 보니 보통 미로 배열에 횟수를 바로 저장해놓는다. 이 방법이 더 좋을 것 같다.
bfs로 해결되는 이유
처음에는 그 칸에 가기까지 제일 짧게 이동한 횟수를 계속해서 업데이트 해야 하지 않을까 생각했다.
하지만 그럴 필요가 없는 것이, visit 배열로 방문여부를 따로 설정하기 때문이다.
bfs는 너비 우선으로 -같은 너비 선상의 노드들 먼저- 방문하기 때문에
그 지점을 방문한 적이 있다는 것은 그 지점까지 가는 최단거리가 이미 나왔다는 뜻과 같다.
따라서 횟수를 따로 업데이트할 필요없이 구현하면 된다.
소스코드
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.LinkedList; import java.util.Arrays; import java.util.StringTokenizer; import java.util.Queue; public class p_2178 { static int N, M; static int[][] map; static boolean[][] visit; static int[] dx = {0, 0, -1, 1}; static int[] dy = {1, -1, 0, 0}; public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String str = br.readLine(); StringTokenizer st = new StringTokenizer(str); N = Integer.parseInt(st.nextToken()); M = Integer.parseInt(st.nextToken()); map = new int[N][M]; visit = new boolean[N][M]; for (int i = 0; i < N; i++) { str = br.readLine(); for (int j = 0; j < M; j++) { map[i][j] = str.charAt(j) - '0'; } } for (int i = 0; i < N; i++) { Arrays.fill(visit[i], false); } System.out.println(bfs()); } public static int bfs() { int count = 0; Queue<Point> queue = new LinkedList<Point>(); queue.offer(new Point(0, 0, 1)); visit[0][0] = true; while (true) { Point p = queue.poll(); if (p.x == N-1 && p.y == M-1) { count = p.dist; break; } for (int i = 0; i < 4; i++) { int x = p.x + dx[i]; int y = p.y + dy[i]; if (x >= 0 && y >= 0 && x < N && y < M) { if (map[x][y] == 1 && !visit[x][y]) { queue.offer(new Point(x, y, p.dist + 1)); visit[x][y] = true; } } } } return count; } } class Point { int x; int y; int dist; Point(int x, int y, int dist) { this.x = x; this.y = y; this.dist = dist; } }
'Algorithm > 문제풀이' 카테고리의 다른 글
[백준] 7576번: 토마토 (0) | 2019.06.20 |
---|---|
[백준] 1697번: 숨바꼭질 (0) | 2019.06.20 |
[백준] 1260번: DFS와 BFS (0) | 2019.06.19 |
[백준] 1912번: 연속합 (0) | 2019.06.13 |
[백준] 1978번: 소수 찾기 (0) | 2019.06.13 |