백준 1926 그림 자바

꾸준하게 달리기~·2023년 6월 29일
0
post-thumbnail

문제는 다음과 같다.
https://www.acmicpc.net/problem/1926

코드는 다음과 같다.

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

public class Main {
    static int[] dr = {-1, 1, 0, 0}; //상, 하, 좌, 우 순서
    static int[] dc = {0, 0, -1, 1};
    static int[][] map;
    static boolean[][] visited;
    static int R, C;
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

        StringTokenizer st1 = new StringTokenizer(br.readLine());
        R = Integer.parseInt(st1.nextToken());
        C = Integer.parseInt(st1.nextToken());
        map = new int[R][C];
        visited = new boolean[R][C];
        
        for(int r = 0 ; r < R ; r++) { //map 채우기
            StringTokenizer st2 = new StringTokenizer(br.readLine());
            for(int c = 0 ; c < C ; c++) {
                map[r][c] = Integer.parseInt(st2.nextToken());
            }
        }
        
        //초깃값 세팅
        int max = 0; //뭉탱이의 최댓값
        int answer = 0; //몇개의 뭉탱이를 돌았는지

        for(int r = 0 ; r < R ; r++) {
            for(int c = 0 ; c < C ;c++) {

                if(visited[r][c] == false && map[r][c] == 1) { //r, c 방문 안했고, map 값이 1이라면


                    int a = BFS(r, c); //BFS 실행시켜서 뭉탱이 돌면서 + 뭉탱이 몇개 돌았는지 return
                    if(max < a) { //돌면서 뭉탱이 안에 몇개있는지 최댓값 갱신
                        max = a;
                    }
                    answer++; //뭉탱이 돌아서 answer ++ 해주기.
                }

            }
        }

        bw.write(String.valueOf(answer) + "\n");
        bw.write(String.valueOf(max));
        bw.flush();
        bw.close();

    }
    
    static int BFS(int r, int c) { //BFS 두가지 역할 수행. 통과한 행렬 체크 + 몇개 통과했는지 리턴(max 값 뽑기)
        Queue<int[]> q = new LinkedList<>();
        int how_many = 0;
        q.add(new int[] {r, c});

        while(!q.isEmpty()) {
            int[] now = q.poll();
            how_many++;
            visited[now[0]][now[1]] = true;


            for(int i = 0 ; i < 4 ; i++) {
                int next_r = now[0] + dr[i];
                int next_c = now[1] + dc[i];

                if(next_r >= 0 && next_c >= 0 && next_r < R && next_c < C && //index 만족하고
                        visited[next_r][next_c] == false && map[next_r][next_c] == 1) { //방문 안했고 값이 1이라면
                       q.add(new int[] {next_r, next_c});
                       visited[next_r][next_c] = true;

                }
            }

        }

        //여기까지 오면 BFS 끝, 몇개돌았는지 return
        return how_many;
    }

}

원래 BFS를 알고있다면, 이해는 쉽다.
내가 해준건,
map을
문제에서 준 조건대로 map[r][c] 값이 1이라면
BFS로 순회하면서
how_many로 몇개를 순회했는지 개수를 세주고,
순회하는 친구들을 visited[r][c] = true로 체크하면서
한번 돌았으면 다시 돌지 못하도록 했다.

예를 들어
111
000
000
의 map을 BFS를 돌면,
1행 1열을 먼저 들어가게 되고,
1행의 뭉탱이 111을 돌게 되며
BFS 매서드의 로직에 의해 how_many는 3이 될거고 (세 개를 돌았으니)
visited[0][0], visited[0][1], visited[0][2]
는 true가 될거다.
해당 visited 행렬이 true가 되니까,

 if(visited[r][c] == false && map[r][c] == 1)

이 로직에 의해 한번 돈 뭉탱이의 내용물들은 다시 돌지 않도록 해주었다.


이렇게 작동하도록 BFS 매서드를 만들었다.
이정도가 이해간다면 더 자세한 내용은 코드를 보며
주석을 보며 읽어내려가면 충분히 이해 갈 것 같다.

profile
반갑습니다~! 좋은하루 보내세요 :)

0개의 댓글