본문 바로가기

Java/Java 알고리즘 인프런

[Ch.08 - BFS] 03. 미로의 최단거리 통로

반응형
11. 미로의 최단거리 통로(BFS)
 

설명

7*7 격자판 미로를 탈출하는 최단경로의 길이를 출력하는 프로그램을 작성하세요.

경로의 길이는 출발점에서 도착점까지 가는데 이동한 횟수를 의미한다.

출발점은 격자의 (1, 1) 좌표이고, 탈출 도착점은 (7, 7)좌표이다. 격자판의 1은 벽이고, 0은 도로이다.

격자판의 움직임은 상하좌우로만 움직인다. 미로가 다음과 같다면

위와 같은 경로가 최단 경로의 길이는 12이다.

입력

첫 번째 줄부터 7*7 격자의 정보가 주어집니다.

출력

첫 번째 줄에 최단으로 움직인 칸의 수를 출력한다. 도착할 수 없으면 -1를 출력한다.

예시 입력 1 

0 0 0 0 0 0 0
0 1 1 1 1 1 0
0 0 0 1 0 0 0
1 1 0 1 0 1 1
1 1 0 1 0 0 0
1 0 0 0 1 0 0
1 0 1 0 0 0 0

예시 출력 1

12


import java.util.*;
class Pos{
  public int x, y;
  Pos(int x, int y){
    this.x=x;
    this.y=y;
  }
  public boolean inValid(int width, int height){
    if(x<1||x>=width||y<1||y>=height) return false;
    return true;
  }
}
public class Main {
  public static void main(String[] args){
		Scanner kb = new Scanner(System.in);
		int [][]maps=new int[8][8];
		for(int i=1;i<=7;i++) {
			for(int j=1;j<=7;j++) {
				maps[i][j]=kb.nextInt();
			}
		}
		System.out.println(solution(maps));
	}
	static int solution(int[][]maps) {
      int height=maps.length;
      int width = maps[0].length;
      int[][] count= new int [height][width];
      boolean[][] right = new boolean[height][width];
      Queue<Pos> q = new LinkedList<>();
      
      q.offer(new Pos(1,1));
      count[1][1]=0;
      right[1][1]=true;
    
      while(!q.isEmpty()){
    	  Pos c = q.poll();
          int currentCount=count[c.y][c.x];
          
        final int[][] dis = {{-1,0}, {0,-1}, {1,0}, {0,1}};
        for(int i=0;i<4;i++){
          Pos moved=new Pos(c.x+dis[i][0], c.y+dis[i][1]);
          if(!moved.inValid(width, height)) continue;
          if(maps[moved.y][moved.x]==1) continue;
          if(right[moved.y][moved.x]) continue;
          
          q.offer(moved);
          count[moved.y][moved.x]=currentCount+1;
          right[moved.y][moved.x]=true;
        }
      }
      
      int answer=count[height-1][width-1];
      
      if(answer==0) return -1;
      return answer;
	}

}

 

import java.util.*;

class Point {
	public int x, y;

	Point(int x, int y) {
		this.x = x;
		this.y = y;
	}
}

class Main {
	static int[] dx = { -1, 0, 1, 0 };
	static int[] dy = { 0, 1, 0, -1 };
	static int[][] board, dis;

	public void BFS(int x, int y) {
		Queue<Point> Q = new LinkedList<>();
		Q.offer(new Point(x, y));
		board[x][y] = 1;
		while (!Q.isEmpty()) {
			Point tmp = Q.poll();
			for (int i = 0; i < 4; i++) {
				int nx = tmp.x + dx[i];
				int ny = tmp.y + dy[i];
				if (nx >= 1 && nx <= 7 && ny >= 1 && ny <= 7 && board[nx][ny] == 0) {
					board[nx][ny] = 1;
					Q.offer(new Point(nx, ny));
					dis[nx][ny] = dis[tmp.x][tmp.y] + 1;
				}
			}
		}
	}

	public static void main(String[] args) {
		Main T = new Main();
		Scanner kb = new Scanner(System.in);
		board = new int[8][8];
		dis = new int[8][8];
		for (int i = 1; i <= 7; i++) {
			for (int j = 1; j <= 7; j++) {
				board[i][j] = kb.nextInt();
			}
		}
		T.BFS(1, 1);
		if (dis[7][7] == 0)
			System.out.println(-1);
		else
			System.out.println(dis[7][7]);
	}
}

 

 

# 큐를 사용하지 않고, DFS로 BFS 구현하는 방법

(1) flag를 이용해서 도착 성공여부 판단

(2) DFS를 돌면서, L이 항상 낮을 때 먼저 끝나는게 아니므로, answer=Math.min(L, answer);

(3) 따라서 flag가 거짓일 때 -1출력, 참일 때 answer 출력

import java.util.Scanner;
class Pos{
  public int x, y;
  Pos(int x, int y){
    this.x=x;
    this.y=y;
  }
  public boolean isValid(int width, int height){
    if(x<0||x>=width){
      return false;
    }
    if(y<0||y>=height){
      return false;
    }
    return true;
  }
}
public class Main {
  static int n=7;
  static int answer=Integer.MAX_VALUE;
  static int[][] arr;
  static boolean flag;
  static final int[][] dis = {{0,1},{0,-1},{1,0},{-1,0}};
  public static void main(String[] args){
    Scanner in=new Scanner(System.in);
    arr= new int[n][n];
    for(int i=0;i<n;i++){
      for(int j=0;j<n;j++){
        arr[i][j]=in.nextInt();
      }
    }
    Pos s = new Pos(0,0);
    DFS(s,0);
    
    if(flag) System.out.println(answer);
    else System.out.println(-1);
    
  }
  static void DFS(Pos p, int L){
    arr[p.x][p.y]=1;
    if(p.x==6 && p.y==6){
      flag=true;
      answer=Math.min(L,answer);
      return;
    }
    else{
    for(int i=0;i<4;i++){
      Pos ns =new Pos(p.x+dis[i][0], p.y+dis[i][1]);
      if(ns.isValid(n,n)&&arr[ns.x][ns.y]==0){
        DFS(ns,L+1);
        arr[ns.x][ns.y]=0;
      }      
    }
    }
  }
}
반응형