Algorithm/이코테

21.인구이동

마닐라 2022. 1. 9. 20:03

📍 문제 설명

💡 접근

x일 동안 인구 이동이 발생하는지 출력하면 되는 문제인데

국경선이 열렸을 경우 묶이는 국가에 대해 그룹번호를 지정해준 뒤

그룹 번호가 n * n (각각의 그룹 번호로 묶여서 인구 이동이 불가능 한 경우) 라면

그 때의 일 수를 출력해주면 된다.

 

 

👩‍💻 코드

import java.util.*;

class Position {
    private int x;
    private int y;

    public Position(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public int getX() {
        return this.x;
    }

    public int getY() {
        return this.y;
    }

    @Override
    public String toString() {
        return  "(" + x + "," + y + ")";
    }
}

public class Main {
    // 땅의 크기(N), L, R 값을 입력받기
    public static int n, l, r;
    public static int totalCount = 0;

    // 전체 나라의 정보(N x N)를 입력받기
    public static int[][] graph;
    public static int[][] unions;

    public static int[] dx = {-1, 0, 1, 0};
    public static int[] dy = {0, -1, 0, 1};

    // 특정 위치에서 출발하여 모든 연합을 체크한 뒤에 데이터 갱신
    public static void process(int x, int y, int index) {
        // (x, y)의 위치와 연결된 나라(연합) 정보를 담는 리스트
        ArrayList<Position> united = new ArrayList<>();
        united.add(new Position(x, y));
        // 너비 우선 탐색 (BFS)을 위한 큐 라이브러리 사용
        Queue<Position> q = new LinkedList<>();
        q.offer(new Position(x, y));
        unions[x][y] = index; // 현재 연합의 번호 할당
        System.out.println("그룹 번호: " + unions[x][y]);
        int summary = graph[x][y]; // 현재 연합의 전체 인구 수
        int count = 1; // 현재 연합의 국가 수
        // 큐가 빌 때까지 반복(BFS)
        System.out.println("좌표를 이용해서 그룹번호로 묶기");
        while (!q.isEmpty()) {
            System.out.println("큐 : " + q);
            Position pos = q.poll();
            x = pos.getX();
            y = pos.getY();
            // 현재 위치에서 4가지 방향을 확인하며
            for (int i = 0; i < 4; i++) {
                int nx = x + dx[i];
                int ny = y + dy[i];
                // 바로 옆에 있는 나라를 확인하여
                if (0 <= nx && nx < n && 0 <= ny && ny < n && unions[nx][ny] == -1) {
                    // 옆에 있는 나라와 인구 차이가 L명 이상, R명 이하라면
                    int gap = Math.abs(graph[nx][ny] - graph[x][y]);
                    if (l <= gap && gap <= r) {
                        q.offer(new Position(nx, ny));
                        // 연합에 추가하기
                        unions[nx][ny] = index;
                        summary += graph[nx][ny];
                        count += 1;
                        united.add(new Position(nx, ny));
                    }
                }
            }
        }
        // 연합 국가끼리 인구를 분배
        for (int i = 0; i < united.size(); i++) {
            x = united.get(i).getX();
            y = united.get(i).getY();
            graph[x][y] = summary / count;
        }
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        n = sc.nextInt();
        l = sc.nextInt();
        r = sc.nextInt();

        graph = new int[n][n];
        unions = new int[n][n];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                graph[i][j] = sc.nextInt();
            }
        }

        // 더 이상 인구 이동을 할 수 없을 때까지 반복
        while (true) {
            System.out.println("dd");
            //모든 값을 -1로 바꾸는 배열하나 만들기
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < n; j++) {
                    unions[i][j] = -1;
                }
            }
            //연합 그룹 번호
            int index = 0;
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < n; j++) {
                    if (unions[i][j] == -1) { // 해당 나라가 아직 처리되지 않았다면
                        System.out.println(Arrays.deepToString(graph));
                        System.out.println(Arrays.deepToString(unions));
                        //해당 위치에서 열리는 국경선 그룹으로 묶기
                        process(i, j, index);
                        index += 1;
                    }
                }
            }
            System.out.println(Arrays.deepToString(graph));
            System.out.println(Arrays.deepToString(unions));
            //연합 그룹 번호가 n * n 이라는 말은 더이상 인구 이동이 불가능하다는 뜻이므로 이때 break;
            if (index == n * n) break;
            totalCount += 1;
        }

        // 인구 이동 횟수 출력
        System.out.println(totalCount);
    }
}

'Algorithm > 이코테' 카테고리의 다른 글

23.국영수  (0) 2022.01.10
22.블록 이동하기  (0) 2022.01.09
20.감시 피하기  (0) 2022.01.09
19.연산자 끼워넣기  (0) 2022.01.09
18.괄호 변환  (0) 2022.01.08