본문 바로가기

Algorithm/문제풀이

[백준] 2178번: 미로탐색

문제링크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