고코딩

[백준 2178번] 미로 탐색 본문

코딩테스트

[백준 2178번] 미로 탐색

고코딩 2021. 1. 14. 11:43

문제

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)의 위치로 이동할 수 있다. 칸을 셀 때에는 시작 위치와 도착 위치도 포함한다.

입력

첫째 줄에 두 정수 N, M(2 ≤ N, M ≤ 100)이 주어진다. 다음 N개의 줄에는 M개의 정수로 미로가 주어진다. 각각의 수들은 붙어서 입력으로 주어진다.

출력

첫째 줄에 지나야 하는 최소의 칸 수를 출력한다. 항상 도착위치로 이동할 수 있는 경우만 입력으로 주어진다.


정답

처음에는 깊이 탐색으로 원하는 좌표까지 가는동안 걸린 거리를 측정했다. 근데 생각해보니 그 길이 가장빠르 길이 아니라는 것을 알고 너비탐색(BFS)로 풀었다.
처음 (1,1) 좌표의 값을 1로 두고 그 주변에 갈수있는 값을 +1한 2값을 넣었다. 그렇게 주변의 갈수있는 칸에 그 칸까지 가기위해 거쳐야하는 칸의 갯수(사실상 가장 가까운 거리)를 입력하면서 탐색하다가, 원하는 좌표에 닿으면 출력하고 끝나게 했다.

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Queue;

public class Main {
    static class Graph{
        //목표좌표
        private int N,M;
        //미로를 구성할 배열
        private int[][] maze;
        //생성자
        //미로 크기 생성
        public Graph(int n, int m) {
            this.maze = new int[n+2][m+2];
            this.N = n;
            this.M = m;
        }
        //미로 구성 함수
        public void addMaze(int row, int[] m) {
            for(int i=0; i<m.length; i++) {
                maze[row][i+1] = m[i];
            }
        }

        //너비우선 탐색
        //BFS
        //while함수로 구현
        //시작위치 (v,w)
        public void BFS(int v, int w) {
            int length = 0;
            //미로중에 방문한 칸은 1로 만든다. 각 칸 마다 깊이를 적을 거임
            maze[v][w] = ++length;

            //BFS구현을 위한 queue생성
            Queue<Node> queue = new LinkedList<Node>();

            //현재 방문한 위치 큐에 넣음
            queue.add(new Node(v,w));

            //큐가 빌때까지 반복
            while(!queue.isEmpty()) {
                Node n = queue.poll();
                if(n.v == N && n.w == M) {
                    System.out.println(maze[n.v][n.w]);
                    break;
                }

                //꺼낸 좌표의 주변 좌표중 길이 있는 것들의 값을 이전 좌표 깊이의 +1해서 저장
                if(maze[n.v-1][n.w] == 1 && (n.v-1 != 1 || n.w !=1) ) {
                    queue.add(new Node(n.v-1, n.w));
                    maze[n.v-1][n.w] = maze[n.v][n.w]+1;
                }
                if(maze[n.v+1][n.w] == 1 && (n.v+1 != 1 || n.w !=1)) {
                    queue.add(new Node(n.v+1, n.w));
                    maze[n.v+1][n.w] = maze[n.v][n.w]+1;
                }
                if(maze[n.v][n.w-1] == 1 && (n.v != 1 || n.w-1 !=1)) {
                    queue.add(new Node(n.v, n.w-1));
                    maze[n.v][n.w-1] = maze[n.v][n.w]+1;
                }
                if(maze[n.v][n.w+1] == 1 && (n.v != 1 || n.w+1 !=1)) {
                    queue.add(new Node(n.v, n.w+1));
                    maze[n.v][n.w+1] = maze[n.v][n.w]+1;
                }
            }

        }
        class Node{
            int v;
            int w;
            public Node(int v, int w) {
                this.v= v;
                this.w = w;
            }
        }

    }
    public static void main(String[] args) throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        StringBuffer sf = new StringBuffer();

        String[] NM = br.readLine().split(" ");

        Graph g = new Graph(Integer.parseInt(NM[0]),Integer.parseInt(NM[1]));

        for(int i=0; i<Integer.parseInt(NM[0]); i++) {
            String miro = br.readLine();
            int [] mm = new int[Integer.parseInt(NM[1])];
            for(int j=0; j<miro.length(); j++) {
                mm[j] = Integer.parseInt(miro.substring(j, j+1));
            }
            g.addMaze(i+1, mm);
        }
        g.BFS(1, 1);

        br.close();
        bw.flush();
        bw.close();
    }
}

'코딩테스트' 카테고리의 다른 글

[백준 7576번] 토마토  (0) 2021.01.18
[백준 2667번] 단지번호붙이기  (0) 2021.01.14
[백준 1260번] DFS와 BFS  (0) 2021.01.13
[백준 2504번] 괄호의 값  (0) 2021.01.12
[백준 4949번] 균형잡힌 세상  (0) 2021.01.11