백준 2589 보물섬 - 자바

손찬호·2024년 5월 31일
0

알고리즘

목록 보기
54/91

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

풀이 아이디어

보물지도의 바다와 육지 유무를 2차원 배열 char[][] map으로 입력받고
반복문 bfs를 사용해 'L'에 해당하는 타일을 완전탐색을 한다.
이때 visited 배열을 사용해 중복된 장소를 탐색하지 않도록 한다.

  1. 입력을 받는다.
  2. 탐색
  3. 결과값 출력

트러블슈팅

java.lang.NullPointerException 발생

Exception in thread "main" java.lang.NullPointerException: Cannot load from object array because "_2589.map" is null
        at _2589.bfs(_2589.java:65)
        at _2589.main(_2589.java:31)

class _2589 안 main함수 안에서 char[][] map = new char[height][width];로 초기화되고
class _2589 안 main함수 밖에서 static char[][] map;
두번 초기화되서 class _2589 안 main함수 밖에 함수 bfs()가 map을 참조할 때 오류가 발생했다.

main()과 bfs() 모두 map을 참조하기 위해서 static char[][] map으로 선언해줬기 때문에

main 함수의 char[][] map = new char[height][width];
map = new char[height][width];로 바꿔줬다.

풀이 코드

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

public class _2589 {
    static int maxMove = 0;
    static char[][] map;
    static boolean[][] visited;
    static int[][] directions = {{-1,0}, {1,0}, {0,-1}, {0,1}};
    static int height;
    static int width;
    public static void main(String[] args) throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        height = Integer.parseInt(st.nextToken());
        width = Integer.parseInt(st.nextToken());
        map = new char[height][width];
        for(int i=0;i<height;i++){
            st = new StringTokenizer(br.readLine());
            String oneLine = st.nextToken();
            for(int j=0;j<width;j++){
                map[i][j] = oneLine.charAt(j);
            }
        }
        // System.out.println(Arrays.deepToString(map));

        // 육지 두 점 사이의 최장거리 찾기 
        for(int i=0;i<height;i++){
            for(int j=0;j<width;j++){
                if(map[i][j]=='L'){
                    visited = new boolean[height][width]; // 탐색을 시작할 때 visited를 초기화해준다.
                    int result = bfs(j,i); // map 기준으로 [y][x]이므로 뒤집어서 넣어준다.
                    maxMove = Math.max(maxMove, result);
                }
            }
        }

        // 어떻게 육지와 바다를 나눠서 탐색할 수 있을까?
        // -> map[ny][nx]='L'인 경우에만 탐색하면 될듯

        System.out.println(maxMove);
    }
    static int bfs(int curX, int curY){
        Queue<int[]> q = new LinkedList<>();
        
        int moveCount = 0;
        visited[curY][curX] = true;
        q.add(new int[] {curX, curY, 0});

        while(!q.isEmpty()){
            int[] position = q.poll();
            int px = position[0];
            int py = position[1];
            int move = position[2];

            if(move > moveCount){
                moveCount = move;
            }

            for(int i=0;i<4;i++){
                int nx = px + directions[i][0];
                int ny = py + directions[i][1];
                if(nx<0 || nx>(width-1) || ny<0 || ny>(height-1)){
                    continue; // 영역을 벗어나면 다음으로 이동
                }
                if(!visited[ny][nx] && map[ny][nx]=='L'){
                    visited[ny][nx] = true;
                    q.add(new int[]{nx, ny, move+1});
                }
            }
        }

        return moveCount;
    }
}
profile
매일 1%씩 성장하려는 주니어 개발자입니다.

0개의 댓글

관련 채용 정보