본문 바로가기
백준

[백준] code.plus(BFS 알고리즘,JAVA)17086번, 아기 상어 2

by 열정적인 이찬형 2022. 7. 16.

문제 링크

 

17086번: 아기 상어 2

첫째 줄에 공간의 크기 N과 M(2 ≤ N, M ≤ 50)이 주어진다. 둘째 줄부터 N개의 줄에 공간의 상태가 주어지며, 0은 빈 칸, 1은 아기 상어가 있는 칸이다. 빈 칸과 상어의 수가 각각 한 개 이상인 입력만

www.acmicpc.net


주의사항

  • JAVA를 사용하여 프로그램을 사용하였습니다.
  • 백준에서 코드를 작성하였을 때 아래 형태에서 Main에서 결과가 출력되어야 합니다.
public class Main{ 	
	public static void main(String[] args){
    }
}

문제 설명


접근 방법

그래프 알고리즘이란?

각 정점과 연결하는 선분의 정보를 가지고 BFS(너비 우선 탐색), DFS(깊이 우선 탐색) .... 등을 이용하여 정점에서 다른 정점으로 가는 최소값, 최대값 등의 문제에서 출력하라는 결과를 구하는 알고리즘입니다.
 

BFS?

BFS(너비 우선 탐색)은 아래 그림처럼 시작 노드에 인접한 노드를 모두 탐색한 후 인접한 노드를 기준으로 다시 인접한 노드를 찾아내는 것을 반복하여 탐색합니다.

시작 노드 탐색이 끝나면 인접했던 노드를 시작 노드로 생각하고 다시 탐색합니다.

출처: https://ko.wikipedia.org/wiki/%EB%84%88%EB%B9%84_%EC%9A%B0%EC%84%A0_%ED%83%90%EC%83%89

더 자세한 내용은 아래 링크에 들어가서 확인해주시면 감사하겠습니다.

 

너비 우선 탐색 - 위키백과, 우리 모두의 백과사전

 

ko.wikipedia.org

 

이 문제에 핵심은

1. 각 공간에서 가장 가까운 아기 상어의 길이가 안전거리이다.

2. 상하좌우, 대각선으로 이동이 가능합니다.

3. 0은 빈 공간, 1은 아기 상어가 존재하는 공간입니다.

4. 안전 거리의 최대값을 결과로 출력합니다.

 

이동하는 칸

 

dx = {-1, 0, 1, -1, 1, -1, 0, 1};
dy = {-1, -1, -1, 0, 0, 1, 1, 1};

 

각 0인 공간에서 BFS탐색을 진행하여 최대값을 얻어서 결과로 출력하였습니다.

 

예제입력 1.

K = 1

해석 : 원숭이는 1번만 체스의 나이트처럼 이동할 수 있습니다.

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

 

각 0인 공간에서 BFS 탐색 시작!

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

 

안전거리의 최대값 2를 결과로 출력한다.

 

  • BufferedReader를 사용하여 입력 값을 받았습니다.
  • StringTokenizer을 이용하여 공간에 대한 정보를 저장하였습니다.
  • 0인 공간에서 아기 상어의 최단 거리를 구하는 bfs함수를 실행하였습니다.
  • 최대 안전거리를 BufferedWriter에 저장합니다.
  • BufferedWriter에 저장된 결과값을 출력하였습니다.
  • bfs는 0인 공간에서 아기 상어까지 BFS탐색으로 최소 이동횟수를 구하는 함수입니다.
  • inSpace은 이동한 좌표가 공간 안에 존재하는지 확인하는 함수입니다.

 

import java.util.*;
import java.io.*;

public class Main {
	//공간에 대한 정보 관련 클래스
    static class position{
        int x, y, count;
        public position(int x, int y, int count) {
            this.x = x;
            this.y = y;
            this.count = count;	//이동한 횟수
        }
    }
    static int N,M;
    static int[][] space;		//공간에 대한 정보 저장 배열
    static int[] dx = {-1, 0, 1, -1, 1, -1, 0, 1};	//이동관련 X 변경값
    static int[] dy = {-1, -1, -1, 0, 0, 1, 1, 1};	//이동관련 y 변경값
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        //입력값 처리하는 BufferedReader
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        //결과값 출력하는 BufferedWriter
        StringTokenizer st = new StringTokenizer(br.readLine()," ");
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        space = new int[N][M];
        //공간에 대한 정보 저장
        for(int i=0;i<N;i++){
            st = new StringTokenizer(br.readLine()," ");
            for(int j=0;j<M;j++){
                space[i][j] = Integer.parseInt(st.nextToken());
            }
        }
        int answer = Integer.MIN_VALUE;
        //공간이 0인 공간 BFS 탐색 진행 및 최대 안전거리 구하기
        for(int i=0;i<N;i++){
            for(int j=0;j<M;j++){
                if(space[i][j] == 0)
                    answer = Math.max(answer, bfs(j, i));
            }
        }
        bw.write(answer + "");	//최대 안전거리 BufferedWriter 저장
        bw.flush();
        bw.close();
        br.close();
    }
    //가장 가까운 아기 상어 거리를 구하는 BFS 탐색 함수
    static int bfs(int x, int y){
        Queue<position> queue = new LinkedList<>();
        boolean[][] visited = new boolean[N][M];
        visited[y][x] = true;
        queue.add(new position(x, y, 0));
        while(!queue.isEmpty()){
            position cur = queue.poll();
            for(int i=0;i<8;i++){	//공간 이동.
                int tempX = cur.x + dx[i];
                int tempY = cur.y + dy[i];
                if(inSpace(tempX,tempY) && !visited[tempY][tempX]){
                    if(space[tempY][tempX]==0){	//빈공간일 때
                        visited[tempY][tempX] = true;
                        queue.add(new position(tempX,tempY, (cur.count+1)));
                    }else{		//아기 상어 만날 때
                        return cur.count+1;
                    }
                }
            }
        }
        return -1;	//아기 상어 못 만날 때
    }
    //좌표가 공간에 벗어나는지 확인하는 함수
    static boolean inSpace(int x, int y){
        if(x>=0 && y>=0 && x<M && y<N)
            return true;
        return false;
    }
}

댓글