개발 블로그
article thumbnail

 

아이디어

1. bfs 탐색을 통해 국경이 열리는 국가들을 하나의 연합으로 묶고

2. (연합 총 인구수 / 연합 국가 수) 를 계산하여 연합으로 묶인 국가들의 인구를 갱신해준다.

3. 이 때 기존 인구 수와 갱신해야 하는 인구 수가 같다면 갱신이 불필요 즉 인구 이동이 일어나지 않으므로 인구 갱신 시 '기존 인구 수와 갱신 인구 수가 같지 않을 때만 인구 이동이 일어났다고 판단한다'

 

매일 새로운 visited 배열과 함께 1 ~ 3 과정을 수행하고 3 과정에서 '인구 이동이 없었다' 라고 판단이 되면 다음 날로 넘어가지 않고 현재까지 며칠이 소요되었는지를 출력하면 된다.

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
import java.util.Queue;

public class _n16234_ {

    static int N;
    static int L;
    static int R;
    static List<int[]> group;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());

        N = Integer.parseInt(st.nextToken());
        L = Integer.parseInt(st.nextToken());
        R = Integer.parseInt(st.nextToken());

        int[][] populations = new int[N][N];
        for (int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine());
            for (int j = 0; j < N; j++) {
                populations[i][j] = Integer.parseInt(st.nextToken());
            }
        }

        /*
        국경선이 open 되는 그룹끼리 묶고,
        각 그룹의 인구 수가 모두 동일하다면 인구 이동 X
        동일하지 않다면 인구 이동 O
         */

        int day = 0;
        while (true) {
            boolean isMove = false;

            boolean[][] visited = new boolean[N][N];
            for (int i = 0; i < N; i++) {
                for (int j = 0; j < N; j++) {
                    if (!visited[i][j]) {
                        group = new ArrayList<>();
                        int groupPopulation = bfs(i, j, populations, visited);
                        if (move(populations, groupPopulation)) {
                            isMove = true;
                        }
                    }
                }
            }

            if (!isMove) break;
            day++;
        }

        System.out.println(day);
    }

    public static int bfs(int i, int j, int[][] populations, boolean[][] visited) {
        int sum = 0;
        int cnt = 0;

        Queue<int[]> queue = new LinkedList<>();
        queue.add(new int[]{i, j});
        group.add(new int[]{i, j});
        visited[i][j] = true;
        sum += populations[i][j];
        cnt++;

        int[] dx = {-1, 1, 0, 0};
        int[] dy = {0, 0, -1, 1};
        while (!queue.isEmpty()) {
            int[] temp = queue.poll();
            int x = temp[0];
            int y = temp[1];

            for (int k = 0; k < 4; k++) {
                int nx = x + dx[k];
                int ny = y + dy[k];

                if (nx < 0 || ny < 0 || nx >= N || ny >= N || visited[nx][ny]) continue;

                int diff = Math.abs(populations[x][y] - populations[nx][ny]);
                if (diff < L || diff > R) continue;

                queue.add(new int[]{nx, ny});
                group.add(new int[]{nx, ny});
                visited[nx][ny] = true;
                sum += populations[nx][ny];
                cnt++;
            }
        }

        return sum / cnt;
    }

    public static boolean move(int[][] populations, int groupPopulation) {
        boolean isMoved = false;

        int L = group.size();

        for (int i = 0; i < L; i++) {
            int[] temp = group.get(i);
            int x = temp[0];
            int y = temp[1];

            if (populations[x][y] != groupPopulation) {
                populations[x][y] = groupPopulation;
                isMoved = true;
            }
        }

        return isMoved;
    }
}

 

'Algorithm > 백준 알고리즘' 카테고리의 다른 글

9251번. LCS  (0) 2023.10.09
12865번. 평범한 배낭  (0) 2023.10.09
18808번. 스티커 붙이기  (1) 2023.10.08
15724번. 주지수  (0) 2023.10.08
2294번. 동전 2  (0) 2023.10.06
profile

개발 블로그

@하얀.손

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!