[백준]#16234 인구이동

SeungBird·2020년 8월 27일
1

⌨알고리즘(백준)

목록 보기
89/401

문제

N×N크기의 땅이 있고, 땅은 1×1개의 칸으로 나누어져 있다. 각각의 땅에는 나라가 하나씩 존재하며, r행 c열에 있는 나라에는 A[r][c]명이 살고 있다. 인접한 나라 사이에는 국경선이 존재한다. 모든 나라는 1×1 크기이기 때문에, 모든 국경선은 정사각형 형태이다.

오늘부터 인구 이동이 시작되는 날이다.

인구 이동은 다음과 같이 진행되고, 더 이상 아래 방법에 의해 인구 이동이 없을 때까지 지속된다.

  • 국경선을 공유하는 두 나라의 인구 차이가 L명 이상, R명 이하라면, 두 나라가 공유하는 국경선을 오늘 하루동안 연다.
  • 위의 조건에 의해 열어야하는 국경선이 모두 열렸다면, 인구 이동을 시작한다.
  • 국경선이 열려있어 인접한 칸만을 이용해 이동할 수 있으면, 그 나라를 오늘 하루 동안은 연합이라고 한다.
  • 연합을 이루고 있는 각 칸의 인구수는 (연합의 인구수) / (연합을 이루고 있는 칸의 개수)가 된다. 편의상 소수점은 버린다.
  • 연합을 해체하고, 모든 국경선을 닫는다.

각 나라의 인구수가 주어졌을 때, 인구 이동이 몇 번 발생하는지 구하는 프로그램을 작성하시오.

입력

첫째 줄에 N, L, R이 주어진다. (1 ≤ N ≤ 50, 1 ≤ L ≤ R ≤ 100)

둘째 줄부터 N개의 줄에 각 나라의 인구수가 주어진다. r행 c열에 주어지는 정수는 A[r][c]의 값이다. (0 ≤ A[r][c] ≤ 100)

인구 이동이 발생하는 횟수가 2,000번 보다 작거나 같은 입력만 주어진다.

출력

인구 이동이 몇 번 발생하는지 첫째 줄에 출력한다.

예제 입력 1

2 20 50
50 30
20 40

예제 출력 1

1

초기 상태는 아래와 같다.

L = 20, R = 50 이기 때문에, 모든 나라 사이의 국경선이 열린다. (열린 국경선은 점선으로 표시)

연합은 하나 존재하고, 연합의 인구는 (50 + 30 + 20 + 40) 이다. 연합의 크기가 4이기 때문에, 각 칸의 인구수는 140/4 = 35명이 되어야 한다.

예제 입력 2

2 40 50
50 30
20 40

예제 출력 2

0

예제 입력 3

2 20 50
50 30
30 40

예제 출력 3

1

예제 입력 4

3 5 10
10 15 20
20 30 25
40 22 10

예제 출력 4

2

예제 입력 5

4 10 50
10 100 20 90
80 100 60 70
70 20 30 40
50 20 100 10

예제 출력 5

3

풀이

이 문제는 BFS 알고리즘을 이용해서 풀었으나 생각해야 할 부분이 조금 많았다.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;

public class Main {
    static int[] dx = {-1, 1, 0, 0};
    static int[] dy = {0, 0, -1, 1};
    static int[][] map;
    static boolean[][] visited;
    static int N;
    static int L;
    static int R;
    static ArrayList<Pair> change = new ArrayList<>();

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

        for(int i=0; i<N; i++) {
            String[] input = br.readLine().split(" ");
            for(int j=0; j<N; j++)
                map[i][j] = Integer.parseInt(input[j]);
        }

        while(true) {
            visited = new boolean[N][N];

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

            if(change.size()==0)
                break;

            result++;

            for(int i=0; i<change.size(); i++) {
                Pair p = change.get(i);
                map[p.x][p.y] = p.ch;
            }
            change.clear();
        }
        System.out.println(result);
    }

    static void bfs(int x, int y) {
        Queue<Pair> queue = new LinkedList<>();
        ArrayList<Pair> list = new ArrayList<>();
        visited[x][y] = true;
        queue.add(new Pair(x, y, 0));
        list.add(new Pair(x, y, 0));
        int sum = map[x][y];
        int cnt = 0;

        while(!queue.isEmpty()) {
            Pair p = queue.poll();

            for(int i=0; i<4; i++) {
                int X = p.x + dx[i];
                int Y = p.y + dy[i];

                if(X>=0 && X<N && Y>=0 && Y<N && !visited[X][Y]) {
                    if(Math.abs(map[X][Y] - map[p.x][p.y])>=L && Math.abs(map[X][Y] - map[p.x][p.y])<=R) {
                        visited[X][Y] = true;
                        queue.add(new Pair(X, Y, 0));
                        list.add(new Pair(X, Y, 0));
                        sum+=map[X][Y];
                        cnt++;
                    }
                }
            }
        }
        if(cnt>0) {
            int n = list.size();
            for(int i=0; i<n; i++) {
                Pair p2 = list.remove(0);
                change.add(new Pair(p2.x, p2.y, sum/(cnt+1)));
            }
        }
    }

    static class Pair {
        int x;
        int y;
        int ch;

        public Pair(int x, int y, int ch) {
            this.x = x;
            this.y = y;
            this.ch = ch;
        }
    }
}
profile
👶🏻Jr. Programmer

0개의 댓글