[JAVA] 백준 (실버1) 2178번 미로 탐색

AIR·2023년 11월 27일
0

링크

https://www.acmicpc.net/problem/2178


문제 설명

(정답률 43.670%)
N×M크기의 배열로 표현되는 미로가 있다.
1 0 1 1 1 1
1 0 1 0 1 0
1 0 1 0 1 1
1 1 1 0 1 1
미로에서 1은 이동할 수 있는 칸을 나타내고, 0은 이동할 수 없는 칸을 나타낸다. 이러한 미로가 주어졌을 때, (1, 1)에서 출발하여 (N, M)의 위치로 이동할 때 지나야 하는 최소의 칸 수를 구하는 프로그램을 작성하시오. 한 칸에서 다른 칸으로 이동할 때, 서로 인접한 칸으로만 이동할 수 있다.

위의 예에서는 15칸을 지나야 (N, M)의 위치로 이동할 수 있다. 칸을 셀 때에는 시작 위치와 도착 위치도 포함한다.


입력 예제

4 6
101111
101010
101011
111011


출력 예제

15


정답 코드

간선의 가중치가 모두 1일 때, 최소 비용 또는 최소 이동 거리는 bfs를 암시하는 대표적인 키워드이다.

다른 문제와 차이점은 갈수 있는 모든 경로를 탐색하는 것이 아니라
목적지까지의 최소 이동 거리를 구해야 한다.
bfs를 이용하여 목적지까지 도착할 때까지 현재 좌표를 갱신해나간다.

예제를 이용하여 미로의 좌표를 갱신하면 다음과 같다.
[1, 0, 9, 10, 11, 12],
[2, 0, 8, 0, 12, 0],
[3, 0, 7, 0, 13, 14],
[4, 5, 6, 0, 14, 15]

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;

public class Main {

	//[0,1], [1,0], [0,-1], [-1,0]
    static final int[] dr = {0, 1, 0, -1};
    static final int[] dc = {1, 0, -1, 0};
    static boolean[][] visit;
    static int[][] maze;
    static int N;
    static int M;

    public static void main(String[] args) throws IOException {

        System.setIn(new FileInputStream("src/input.txt"));
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());

        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        visit = new boolean[N][M];
        
        //미로 배열 생성 및 할당
		maze = new int[N][M];
        for (int i = 0; i < N; i++) {
            int[] temp = Arrays.stream(br.readLine().split(""))
            		.mapToInt(Integer::parseInt).toArray();
            maze[i] = temp;
        }

        bfs(0, 0);

        System.out.println(maze[N - 1][M - 1]);
    }
    
    //너비 우선 탐색 메서드
    static void bfs(int r, int c) {
        Queue<int[]> queue = new LinkedList<>();
        visit[r][c] = true;
        queue.add(new int[]{r, c});
		
        //큐가 빌 때까지 반복
        while (!queue.isEmpty()) {
            int[] curPos = queue.poll();
            int curR = curPos[0];
            int curC = curPos[1];

			//상하좌우 탐색
            for (int i = 0; i < 4; i++) {
                int nextR = curR + dr[i];
                int nextC = curC + dc[i];
                
				//배열을 벗어날 경우 
                if (nextR < 0 || nextR >= N || nextC < 0 || nextC >= M) {
                    continue;
                }

				//방문하지 않고 원소가 1일 때
                if (!visit[nextR][nextC] && maze[nextR][nextC] == 1) {
                	//방문 처리
                    visit[nextR][nextC] = true;
                    //원소 갱신
                    maze[nextR][nextC] = maze[curR][curC] + 1;
                    //큐에 추가
                    queue.add(new int[]{nextR, nextC});
                }
            }
        }
    }
}
profile
백엔드

0개의 댓글