μ•Œκ³ λ¦¬μ¦˜/λ°±μ€€

[ λ°±μ€€ / BOJ 16234 ] 인ꡬ 이동 ( JAVA )

KIMHYEYUN 2022. 1. 30. 02:34
λ°˜μ‘ν˜•

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

 

16234번: 인ꡬ 이동

N×N크기의 땅이 있고, 땅은 1×1개의 칸으둜 λ‚˜λˆ„μ–΄μ Έ μžˆλ‹€. 각각의 λ•…μ—λŠ” λ‚˜λΌκ°€ ν•˜λ‚˜μ”© μ‘΄μž¬ν•˜λ©°, rν–‰ c열에 μžˆλŠ” λ‚˜λΌμ—λŠ” A[r][c]λͺ…이 μ‚΄κ³  μžˆλ‹€. μΈμ ‘ν•œ λ‚˜λΌ μ‚¬μ΄μ—λŠ” ꡭ경선이 μ‘΄μž¬ν•œλ‹€. λͺ¨

www.acmicpc.net

문제


N×N크기의 땅이 있고, 땅은 1×1개의 칸으둜 λ‚˜λˆ„μ–΄μ Έ μžˆλ‹€. 각각의 λ•…μ—λŠ” λ‚˜λΌκ°€ ν•˜λ‚˜μ”© μ‘΄μž¬ν•˜λ©°, rν–‰ c열에 μžˆλŠ” λ‚˜λΌμ—λŠ” A[r][c]λͺ…이 μ‚΄κ³  μžˆλ‹€. μΈμ ‘ν•œ λ‚˜λΌ μ‚¬μ΄μ—λŠ” ꡭ경선이 μ‘΄μž¬ν•œλ‹€. λͺ¨λ“  λ‚˜λΌλŠ” 1×1 크기이기 λ•Œλ¬Έμ—, λͺ¨λ“  ꡭ경선은 μ •μ‚¬κ°ν˜• ν˜•νƒœμ΄λ‹€.

μ˜€λŠ˜λΆ€ν„° 인ꡬ 이동이 μ‹œμž‘λ˜λŠ” 날이닀.

인ꡬ 이동은 ν•˜λ£¨ λ™μ•ˆ λ‹€μŒκ³Ό 같이 μ§„ν–‰λ˜κ³ , 더 이상 μ•„λž˜ 방법에 μ˜ν•΄ 인ꡬ 이동이 없을 λ•ŒκΉŒμ§€ μ§€μ†λœλ‹€.

  • ꡭ경선을 κ³΅μœ ν•˜λŠ” 두 λ‚˜λΌμ˜ 인ꡬ 차이가 Lλͺ… 이상, Rλͺ… μ΄ν•˜λΌλ©΄, 두 λ‚˜λΌκ°€ κ³΅μœ ν•˜λŠ” ꡭ경선을 였늘 ν•˜λ£¨ λ™μ•ˆ μ—°λ‹€.
  • μœ„μ˜ 쑰건에 μ˜ν•΄ μ—΄μ–΄μ•Όν•˜λŠ” ꡭ경선이 λͺ¨λ‘ μ—΄λ Έλ‹€λ©΄, 인ꡬ 이동을 μ‹œμž‘ν•œλ‹€.
  • ꡭ경선이 μ—΄λ €μžˆμ–΄ μΈμ ‘ν•œ μΉΈλ§Œμ„ μ΄μš©ν•΄ 이동할 수 있으면, κ·Έ λ‚˜λΌλ₯Ό 였늘 ν•˜λ£¨ λ™μ•ˆμ€ 연합이라고 ν•œλ‹€.
  • 연합을 이루고 μžˆλŠ” 각 칸의 μΈκ΅¬μˆ˜λŠ” (μ—°ν•©μ˜ 인ꡬ수) / (연합을 이루고 μžˆλŠ” 칸의 개수)κ°€ λœλ‹€. νŽΈμ˜μƒ μ†Œμˆ˜μ μ€ 버린닀.
  • 연합을 ν•΄μ²΄ν•˜κ³ , λͺ¨λ“  ꡭ경선을 λ‹«λŠ”λ‹€.

각 λ‚˜λΌμ˜ μΈκ΅¬μˆ˜κ°€ μ£Όμ–΄μ‘Œμ„ λ•Œ, 인ꡬ 이동이 λ©°μΉ  λ™μ•ˆ λ°œμƒν•˜λŠ”μ§€ κ΅¬ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜μ‹œμ˜€.

μž…λ ₯


첫째 쀄에 N, L, R이 μ£Όμ–΄μ§„λ‹€. (1 \(\leq\)N \(\leq\)50, 1 \(\leq\) L \(\leq\) R \(\leq\) 100)

λ‘˜μ§Έ 쀄뢀터 N개의 쀄에 각 λ‚˜λΌμ˜ μΈκ΅¬μˆ˜κ°€ μ£Όμ–΄μ§„λ‹€. rν–‰ c열에 μ£Όμ–΄μ§€λŠ” μ •μˆ˜λŠ” A[r][c]의 값이닀. (0 \(\leq\) A[r][c] \(\leq\) 100)

인ꡬ 이동이 λ°œμƒν•˜λŠ” μΌμˆ˜κ°€ 2,000번 보닀 μž‘κ±°λ‚˜ 같은 μž…λ ₯만 μ£Όμ–΄μ§„λ‹€.

좜λ ₯


인ꡬ 이동이 λ©°μΉ  λ™μ•ˆ λ°œμƒν•˜λŠ”μ§€ 첫째 쀄에 좜λ ₯ν•œλ‹€.

풀이


BFSλ₯Ό μ΄μš©ν•΄ 풀이

solution() : 각 λ‚˜λΌλ₯Ό λŒλ©΄μ„œ ꡭ경선이 μ—΄λ ΈλŠ”μ§€ 확인
⬇️
isOpen(int i, int j)

  • BFS둜 μΈμ ‘ν•œ λ‚˜λΌλ“€κ³Ό 인ꡬ μˆ˜κ°€ L이상 Rμ΄ν•˜μ΄λ©΄ ꡭ경선을 μ˜€ν”ˆ
  • union List에 μΆ”κ°€
  • 인ꡬ 수λ₯Ό population / union.size()둜 λ³€κ²½

μ½”λ“œ


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

public class Main_BOJ_16234_인ꡬ이동 {
    static int N, L, R;
    static int[][] countries;
    static boolean[][] isVisited;
    static int[] dx = {-1, 0, 0, 1};
    static int[] dy = {0, -1, 1, 0};
    static Queue<int[]> queue;
    static List<int[]> union;

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

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

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

        int result = solution();
        System.out.println(result);

    }

    private static int solution() {
        int cnt = 0;
        boolean isMove;

        while (true) {
            isVisited = new boolean[N][N];
            isMove = false;

            for (int i = 0; i < N; i++) {
                for (int j = 0; j < N; j++) {
                    if(isVisited[i][j]) continue;
                    if(isOpen(i,j)) isMove = true;
                }
            }

            if(isMove) cnt++;
            else return cnt;
        }
    }

    private static boolean isOpen(int i, int j) {
        queue = new LinkedList<>();
        union = new ArrayList<>();

        queue.add(new int[]{i, j});
        union.add(new int[]{i, j});
        isVisited[i][j] = true;

        int population = countries[i][j];

        while (!queue.isEmpty()) {
            int[] now = queue.poll();

            for (int d = 0; d < 4; d++) {
                int nx = now[0] + dx[d];
                int ny = now[1] + dy[d];

                if (nx < 0 || N <= nx || ny < 0 || N <= ny || isVisited[nx][ny]) continue;
                int dif = Math.abs(countries[now[0]][now[1]] - countries[nx][ny]);
                if(dif < L || R < dif) continue;

                population += countries[nx][ny];
                queue.add(new int[]{nx, ny});
                union.add(new int[]{nx, ny});
                isVisited[nx][ny] = true;
            }
        }

        if(union.size() < 2) return false;

        int tmp = population / union.size();
        for (int[] u : union) {
            countries[u[0]][u[1]] = tmp;
        }
        return true;


    }
}
728x90
λ°˜μ‘ν˜•