백준 인구 이동

KIMYEONGJUN·2026년 3월 8일
post-thumbnail

문제

내가 생각했을때 문제에서 원하는부분

첫째 줄에 N, L, R이 주어진다. (1 ≤ N ≤ 50, 1 ≤ L ≤ R ≤ 100)
둘째 줄부터 N개의 줄에 각 나라의 인구수가 주어진다.
r행 c열에 주어지는 정수는 A[r][c]의 값이다. (0 ≤ A[r][c] ≤ 100)
인구 이동이 발생하는 일수가 2,000번 보다 작거나 같은 입력만 주어진다.

인구 이동이 며칠 동안 발생하는지 첫째 줄에 출력한다.

내가 이 문제를 보고 생각해본 부분

입력 받기:
N, L, R과 인구 배열 A를 입력받아 저장한다.
메인 반복문:
인구 이동이 더 이상 발생하지 않을 때까지 무한 반복한다.
visited 배열을 초기화하여 아직 방문하지 않은 나라를 확인한다.
BFS 탐색:
방문하지 않은 나라부터 BFS를 시작하여 인구 차이가 조건에 맞으면 인접한 나라들을 연합으로 묶는다.
연합의 모든 나라 좌표를 저장하고 인구 합을 계산한다.
인구 이동 발생 여부 판단:
연합의 크기가 1이라면 인구 이동이 없으므로 아무 변화가 없다.
연합 크기가 2 이상이면 인구 이동이 발생한 것이고, 연합 내 모든 나라 인구수를 평균으로 갱신한다.
날 수 카운트:
인구 이동이 하루 동안이라도 발생하면 days 값을 증가시키고 계속 반복한다.
그렇지 않으면 현재 days를 출력하고 종료한다.

코드로 구현

package baekjoon.baekjoon_33;

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

// 백준 16234번 문제
public class Main1320 {
    static int N, L, R;
    static int[][] A;
    static boolean[][] visited;
    static int[] dr = {-1, 1, 0, 0};
    static int[] dc = {0, 0, -1, 1};

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String[] line = br.readLine().split(" ");
        N = Integer.parseInt(line[0]);
        L = Integer.parseInt(line[1]);
        R = Integer.parseInt(line[2]);

        A = new int[N][N];
        for(int i = 0; i < N; i++) {
            line = br.readLine().split(" ");
            for(int j = 0; j < N; j++) {
                A[i][j] = Integer.parseInt(line[j]);
            }
        }

        int days = 0;
        while(true) {
            visited = new boolean[N][N];
            boolean isMoved = false;

            for(int i = 0; i < N; i++) {
                for(int j = 0; j < N; j++) {
                    if(!visited[i][j]) {
                        if(bfs(i, j)) {
                            isMoved = true;
                        }
                    }
                }
            }

            if(!isMoved) {
                break;
            }
            days++;
        }

        System.out.println(days);
        br.close();
    }

    // 연합을 구성하고 인구 이동을 수행하는 BFS 메서드
    static boolean bfs(int r, int c) {
        Queue<int[]> queue = new LinkedList<>();
        List<int[]> union = new ArrayList<>();

        queue.offer(new int[]{r, c});
        union.add(new int[]{r, c});
        visited[r][c] = true;
        int sum = A[r][c];

        while(!queue.isEmpty()) {
            int[] curr = queue.poll();
            int cr = curr[0];
            int cc = curr[1];

            for(int d = 0; d < 4; d++) {
                int nr = cr + dr[d];
                int nc = cc + dc[d];

                if(nr >= 0 && nr < N && nc >= 0 && nc < N && !visited[nr][nc]) {
                    int diff = Math.abs(A[cr][cc] - A[nr][nc]);
                    if(diff >= L && diff <= R) {
                        visited[nr][nc] = true;
                        queue.offer(new int[]{nr, nc});
                        union.add(new int[]{nr, nc});
                        sum += A[nr][nc];
                    }
                }
            }
        }

        if(union.size() == 1) {
            return false; // 인구 이동 없었음
        }

        int newPopulation = sum / union.size();
        for(int[] pos : union) {
            A[pos[0]][pos[1]] = newPopulation;
        }

        return true; // 인구 이동 발생
    }
}

마무리

코드와 설명이 부족할수 있습니다. 코드를 보시고 문제가 있거나 코드 개선이 필요한 부분이 있다면 댓글로 말해주시면 감사한 마음으로 참고해 코드를 수정 하겠습니다.

profile
Junior backend developer

0개의 댓글