πŸ“– [λ°±μ€€μ•Œκ³ λ¦¬μ¦˜ 풀이] Q.2630 색쒅이 λ§Œλ“€κΈ° 문제 풀이 - java

πŸ“– 문제

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

μ•„λž˜ <κ·Έλ¦Ό 1>κ³Ό 같이 μ—¬λŸ¬κ°œμ˜ μ •μ‚¬κ°ν˜•μΉΈλ“€λ‘œ 이루어진 μ •μ‚¬κ°ν˜• λͺ¨μ–‘μ˜ 쒅이가 μ£Όμ–΄μ Έ 있고, 각 μ •μ‚¬κ°ν˜•λ“€μ€ ν•˜μ–€μƒ‰μœΌλ‘œ μΉ ν•΄μ Έ μžˆκ±°λ‚˜

νŒŒλž€μƒ‰μœΌλ‘œ μΉ ν•΄μ Έ μžˆλ‹€. 주어진 쒅이λ₯Ό μΌμ •ν•œ κ·œμΉ™μ— 따라 μž˜λΌμ„œ λ‹€μ–‘ν•œ 크기λ₯Ό 가진 μ •μ‚¬κ°ν˜• λͺ¨μ–‘μ˜ ν•˜μ–€μƒ‰ λ˜λŠ” νŒŒλž€μƒ‰ 색쒅이λ₯Ό λ§Œλ“€λ €κ³  ν•œλ‹€.

κ·Έλ¦Ό 1

전체 μ’…μ΄μ˜ 크기가 NΓ—N(N=2k, kλŠ” 1 이상 7 μ΄ν•˜μ˜ μžμ—°μˆ˜) 이라면 쒅이λ₯Ό 자λ₯΄λŠ” κ·œμΉ™μ€ λ‹€μŒκ³Ό κ°™λ‹€.

전체 쒅이가 λͺ¨λ‘ 같은 μƒ‰μœΌλ‘œ μΉ ν•΄μ Έ μžˆμ§€ μ•ŠμœΌλ©΄ κ°€λ‘œμ™€ μ„Έλ‘œλ‘œ 쀑간 뢀뢄을 μž˜λΌμ„œ <κ·Έλ¦Ό 2>의 I, II, III, IV와 같이 λ˜‘κ°™μ€ 크기의 λ„€ 개의 N/2 Γ— N/2μƒ‰μ’…μ΄λ‘œ λ‚˜λˆˆλ‹€.

λ‚˜λˆ„μ–΄μ§„ 쒅이 I, II, III, IV 각각에 λŒ€ν•΄μ„œλ„ μ•žμ—μ„œμ™€ λ§ˆμ°¬κ°€μ§€λ‘œ λͺ¨λ‘ 같은 μƒ‰μœΌλ‘œ μΉ ν•΄μ Έ μžˆμ§€ μ•ŠμœΌλ©΄ 같은 λ°©λ²•μœΌλ‘œ λ˜‘κ°™μ€ 크기의 λ„€ 개의 μƒ‰μ’…μ΄λ‘œ λ‚˜λˆˆλ‹€.

이와 같은 과정을 μž˜λΌμ§„ 쒅이가 λͺ¨λ‘ ν•˜μ–€μƒ‰ λ˜λŠ” λͺ¨λ‘ νŒŒλž€μƒ‰μœΌλ‘œ μΉ ν•΄μ Έ μžˆκ±°λ‚˜, ν•˜λ‚˜μ˜ μ •μ‚¬κ°ν˜• 칸이 λ˜μ–΄ 더 이상 자λ₯Ό 수 없을 λ•ŒκΉŒμ§€ λ°˜λ³΅ν•œλ‹€.

μœ„μ™€ 같은 κ·œμΉ™μ— 따라 μž˜λžμ„ λ•Œ <κ·Έλ¦Ό 3>은 <κ·Έλ¦Ό 1>의 쒅이λ₯Ό 처음 λ‚˜λˆˆ ν›„μ˜ μƒνƒœλ₯Ό, <κ·Έλ¦Ό 4>λŠ” 두 번째 λ‚˜λˆˆ ν›„μ˜ μƒνƒœλ₯Ό,

<κ·Έλ¦Ό 5>λŠ” μ΅œμ’…μ μœΌλ‘œ λ§Œλ“€μ–΄μ§„ λ‹€μ–‘ν•œ 크기의 9μž₯의 ν•˜μ–€μƒ‰ 색쒅이와 7μž₯의 νŒŒλž€μƒ‰ 색쒅이λ₯Ό 보여주고 μžˆλ‹€.

κ·Έλ¦Ό 2-5

μž…λ ₯으둜 주어진 μ’…μ΄μ˜ ν•œ λ³€μ˜ 길이 Nκ³Ό 각 μ •μ‚¬κ°ν˜•μΉΈμ˜ 색(ν•˜μ–€μƒ‰ λ˜λŠ” νŒŒλž€μƒ‰)이 μ£Όμ–΄μ§ˆ λ•Œ μž˜λΌμ§„ ν•˜μ–€μƒ‰ 색쒅이와 νŒŒλž€μƒ‰ μƒ‰μ’…μ΄μ˜ 개수λ₯Ό κ΅¬ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜μ‹œμ˜€.

πŸ” 접근법

Q.2630 색쒅이 λ§Œλ“€κΈ° λ¬Έμ œμž…λ‹ˆλ‹€.

주어진 쒅이λ₯Ό μΌμ •ν•œ κ·œμΉ™μ— 따라 μž˜λΌμ„œ λ‹€μ–‘ν•œ 크기λ₯Ό 가진 μ •μ‚¬κ°ν˜• λͺ¨μ–‘μ˜ ν•˜μ–€μƒ‰ λ˜λŠ” νŒŒλž€μƒ‰ 쒅이λ₯Ό λ§Œλ“€κ³  각각 λͺ‡κ°œμΈμ§€λ₯Ό

κ΅¬ν•˜λŠ” λ¬Έμ œμž…λ‹ˆλ‹€.

κ·œμΉ™λ“€μ€ λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€. λ§Œμ•½ 전체 쒅이가 λͺ¨λ‘ 같은 μƒ‰μœΌλ‘œ μΉ ν•΄μ Έ μžˆμ§€ μ•ŠλŠ”λ‹€λ©΄ κ°€λ‘œμ™€ μ„Έλ‘œλ‘œ 쀑간 뢀뢄을 잘라

λ˜‘κ°™μ€ μ •μ‚¬κ°ν˜• 크기둜 4등뢄을 μžλ¦…λ‹ˆλ‹€. μ •μ‚¬κ°ν˜•μ˜ 색쒅이가 λͺ¨λ‘ 같은 색이 될 λ•Œ κΉŒμ§€ 4λ“±λΆ„μœΌλ‘œ λ‚˜λˆ•λ‹ˆλ‹€.

κ·œμΉ™μ— λ§žλŠ”μ§€ 확인을 ν•˜κ³  λ§žμ§€ μ•ŠλŠ”λ‹€λ©΄ 4λ“±λΆ„μœΌλ‘œ λ‚˜λˆ μ§€κΈ°λ₯Ό λ°˜λ³΅ν•©λ‹ˆλ‹€.

κ·œμΉ™μ— λ§žμ„ λ•ŒκΉŒμ§€ λΆ„ν• ν•˜κ³  κ·œμΉ™μ— λ§žμ„ λ•Œ μ •λ³΅ν•©λ‹ˆλ‹€.

λΆ„ν•  μ •λ³΅λ²•μœΌλ‘œ 풀이가 κ°€λŠ₯ν•©λ‹ˆλ‹€.

λ¬Έμ œμ—μ„œ 주어진 κ·œμΉ™λŒ€λ‘œ

μ£Όμ–΄μ§€λŠ” 쒅이가 λͺ¨λ‘ 같은 색인지 ν™•μΈν•©λ‹ˆλ‹€.

주어진 쒅이가 같은 색이 μ•„λ‹ˆλΌλ©΄

4λ“±λΆ„μœΌλ‘œ λ‚˜λˆ μ•Ό ν•˜λŠ”λ° μΌμ •ν•˜κ²Œ κ°€λ‘œ μ„Έλ‘œλ₯Ό 반으둜 μ ‘μ–΄ λ‚˜λˆ•λ‹ˆλ‹€.

μž¬κ·€λ₯Ό 톡해 4λ“±λΆ„μœΌλ‘œ λ‚˜λˆ„λŠ” 것을 λ°˜λ³΅ν•˜λ‹€ 주어진 쒅이가 λͺ¨λ‘ 같은색이 될 λ•Œ

ν•΄λ‹Ή μƒ‰μƒμ˜ 개수λ₯Ό 늘렀주면 λ©λ‹ˆλ‹€.

μ΅œμ’…μ μœΌλ‘œ ν•˜μ–€μƒ‰ 색쒅이와 νŒŒλž€μƒ‰ μƒ‰μ’…μ΄μ˜ 값을 ꡬ할 수 μžˆκ²Œλ©λ‹ˆλ‹€.

πŸ’» μ½”λ“œ


package problem.divide_conquer;

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

public class Main_2630 {
    static int n;
    static int paper[][];
    static int blue = 0;
    static int white = 0;

    public static void main(String[] args) throws IOException {
        input();
        solve(0, 0, n);
        System.out.println(white);
        System.out.println(blue);
    }

    public static void input() throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        n = Integer.parseInt(br.readLine());
        paper = new int[n][n];
        for (int i = 0; i < n; i++) {
            String[] input = br.readLine().split(" ");
            for (int j = 0; j < n; j++) {
                paper[i][j] = Integer.parseInt(input[j]);
            }
        }

        br.close();
    }

    public static void solve(int startX, int startY, int len) {
        if (check(startX, startY, len)) {
            if (paper[startY][startX] == 1) {
                blue++;
            } else {
                white++;
            }
        } else {
            int length = len / 2;
            solve(startX, startY, length);
            solve(startX + length, startY, length);
            solve(startX, startY + length, length);
            solve(startX + length, startY + length, length);
        }
    }

    public static boolean check(int startX, int startY, int len) {
        int color = paper[startY][startX];
        for (int i = startY; i < startY + len; i++) {
            for (int j = startX; j < startX + len; j++) {

                if (color != paper[i][j]) {
                    return false;
                }
            }
        }
        return true;
    }
}

Written on March 15, 2021