본문 바로가기
Algorithm/백준풀이

[알고리즘 문제풀이] 백준 2667_단지번호붙이기(JAVA)

by 계범 2022. 1. 14.

목차

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

     

    2667번: 단지번호붙이기

    <그림 1>과 같이 정사각형 모양의 지도가 있다. 1은 집이 있는 곳을, 0은 집이 없는 곳을 나타낸다. 철수는 이 지도를 가지고 연결된 집의 모임인 단지를 정의하고, 단지에 번호를 붙이려 한다. 여

    www.acmicpc.net

    /**
     * dfs& bfs 풀이(bfs 사용)
     * 
     * 1. 지도를 돌면서, 집을 만나면 bfs 실행
     * 
     * 2. bfs로 방문여부 및 개수 파악(각 번호 카운트 증가)
     * 
     * 3. bfs 종료 시 각 카운트 번호 출력
     * 
     * 4. 다시 지도 돌면서 체크(방문여부로 체크된 곳은 건너뛰기)
     */
    
    import java.util.*;
    import java.io.*;
    
    public class BJ2667_단지번호붙이기 {
        
        public static int n;
        public static int[][] arr;
        public static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        public static void main(String[] args) throws IOException {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        
            n = Integer.parseInt(br.readLine());
            
            arr = new int[n][n];
    
    
            for(int i = 0; i < n; i++){
                String str = br.readLine();
                for(int j = 0; j < n; j++){
                    arr[i][j] = str.charAt(j) -'0';
                }
            }
            bfs();
            bw.flush();
            bw.close();
        }
    
        // 지도 돌면서 bfs 실행
        public static void bfs() throws IOException{
    
            boolean[][] visited = new boolean[n][n];
            Queue<int[]> q = new LinkedList<>();
            
            // 단지수 변수
            int apt = 0;
            // 단지별 집 수
            ArrayList<Integer> alist = new ArrayList<>();
            // 4방향 돌기위한 배열
            int[] dirX = {0,0,1,-1};
            int[] dirY = {1,-1,0,0};
            // 지도 돌기
            for(int i = 0; i < n; i++){
                for(int j = 0; j < n; j++){
                    // 방문하지 않았고, 집이면
                    if(visited[i][j] == false && arr[i][j] == 1){
                        apt++;
                        // 큐에 좌표 담기
                        q.offer(new int[] {i,j});
                        visited[i][j] = true;
                        int cnt = 1;
    
                        //bfs 실행
                        while(!q.isEmpty()){
                            int[] cur = q.poll();
                            // 동서북남 돌기
                            for(int k = 0; k <4; k++){
                                int newX = cur[0] + dirX[k];
                                int newY = cur[1] + dirY[k];
                                // 지도내에 있는가
                                if(0 <= newX && newX < n && 0<= newY && newY < n){
                                    // 방문하지 않았던 곳이면서 집이면,
                                    if(visited[newX][newY] == false && arr[newX][newY] == 1){
                                        visited[newX][newY] = true; // 방문처리
                                        cnt++; // 카운트 증가
                                        q.offer(new int[] {newX,newY});
                                    }
                                }
                            }
                        }
                        // 다했으면 개수 저장
                        alist.add(cnt);
                    }
                }
            }
    
            //아파트 단지와 개수 출력(개수 출력시 오름차순 정렬)
            bw.write(apt +"\n");
            Collections.sort(alist);
            for(int cnt : alist){
                bw.write(cnt +"\n");
            }
        }
    
      
    }

    댓글