μ•Œκ³ λ¦¬μ¦˜

[Java] BOJ 2630 색쒅이 λ§Œλ“€κΈ°

🍊귀🍊 2024. 8. 5. 23:10

문제 

문제 링크 https://www.acmicpc.net/problem/2630

  • μ•„λž˜ <κ·Έλ¦Ό 1>κ³Ό 같이 μ—¬λŸ¬κ°œμ˜ μ •μ‚¬κ°ν˜•μΉΈλ“€λ‘œ 이루어진 μ •μ‚¬κ°ν˜• λͺ¨μ–‘μ˜ 쒅이가 μ£Όμ–΄μ Έ 있고, 각 μ •μ‚¬κ°ν˜•λ“€μ€ ν•˜μ–€μƒ‰μœΌλ‘œ μΉ ν•΄μ Έ μžˆκ±°λ‚˜ νŒŒλž€μƒ‰μœΌλ‘œ μΉ ν•΄μ Έ μžˆλ‹€.
  • μ£Όμ–΄μ§„ 쒅이λ₯Ό μΌμ •ν•œ κ·œμΉ™μ— 따라 μž˜λΌμ„œ λ‹€μ–‘ν•œ 크기λ₯Ό κ°€μ§„ μ •μ‚¬κ°ν˜• λͺ¨μ–‘μ˜ ν•˜μ–€μƒ‰ λ˜λŠ” νŒŒλž€μƒ‰ 색쒅이λ₯Ό λ§Œλ“€λ €κ³  ν•œλ‹€.
  • 전체 μ’…μ΄μ˜ 크기가 N×N(N=2k, kλŠ” 1 이상 7 μ΄ν•˜μ˜ μžμ—°μˆ˜) 이라면 쒅이λ₯Ό 자λ₯΄λŠ” κ·œμΉ™μ€ λ‹€μŒκ³Ό κ°™λ‹€.
  • μœ„μ™€ 같은 κ·œμΉ™μ— 따라 μž˜λžμ„ λ•Œ <κ·Έλ¦Ό 3>은 <κ·Έλ¦Ό 1>의 쒅이λ₯Ό 처음 λ‚˜λˆˆ ν›„μ˜ μƒνƒœλ₯Ό, <κ·Έλ¦Ό 4>λŠ” 두 번째 λ‚˜λˆˆ ν›„μ˜ μƒνƒœλ₯Ό, <κ·Έλ¦Ό 5>λŠ” μ΅œμ’…μ μœΌλ‘œ λ§Œλ“€μ–΄μ§„ λ‹€μ–‘ν•œ 크기의 9μž₯의 ν•˜μ–€μƒ‰ 색쒅이와 7μž₯의 νŒŒλž€μƒ‰ 색쒅이λ₯Ό 보여주고 μžˆλ‹€.
  • 전체 쒅이가 λͺ¨λ‘ 같은 μƒ‰μœΌλ‘œ μΉ ν•΄μ Έ μžˆμ§€ μ•ŠμœΌλ©΄ κ°€λ‘œμ™€ μ„Έλ‘œλ‘œ 쀑간 뢀뢄을 μž˜λΌμ„œ <κ·Έλ¦Ό 2>의 I, II, III, IV와 같이 λ˜‘κ°™μ€ 크기의 λ„€ 개의 N/2 × N/2μƒ‰μ’…μ΄λ‘œ λ‚˜λˆˆλ‹€.
  • λ‚˜λˆ„μ–΄μ§„ 쒅이 I, II, III, IV 각각에 λŒ€ν•΄μ„œλ„ μ•žμ—μ„œμ™€ λ§ˆμ°¬κ°€μ§€λ‘œ λͺ¨λ‘ 같은 μƒ‰μœΌλ‘œ μΉ ν•΄μ Έ μžˆμ§€ μ•ŠμœΌλ©΄ 같은 λ°©λ²•μœΌλ‘œ λ˜‘κ°™μ€ 크기의 λ„€ 개의 μƒ‰μ’…μ΄λ‘œ λ‚˜λˆˆλ‹€.
  • 이와 같은 과정을 μž˜λΌμ§„ 쒅이가 λͺ¨λ‘ ν•˜μ–€μƒ‰ λ˜λŠ” λͺ¨λ‘ νŒŒλž€μƒ‰μœΌλ‘œ μΉ ν•΄μ Έ μžˆκ±°λ‚˜, ν•˜λ‚˜μ˜ μ •μ‚¬κ°ν˜• 칸이 λ˜μ–΄ 더 이상 자λ₯Ό 수 없을 λ•ŒκΉŒμ§€ λ°˜λ³΅ν•œλ‹€.
  • μž…λ ₯으둜 μ£Όμ–΄μ§„ μ’…μ΄μ˜ ν•œ λ³€μ˜ 길이 Nκ³Ό 각 μ •μ‚¬κ°ν˜•μΉΈμ˜ 색(ν•˜μ–€μƒ‰ λ˜λŠ” νŒŒλž€μƒ‰)이 μ£Όμ–΄μ§ˆ λ•Œ μž˜λΌμ§„ ν•˜μ–€μƒ‰ 색쒅이와 νŒŒλž€μƒ‰ μƒ‰μ’…μ΄μ˜ 개수λ₯Ό κ΅¬ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜μ‹œμ˜€.
  • 첫째 μ€„μ—λŠ” 전체 μ’…μ΄μ˜ ν•œ λ³€μ˜ 길이 N이 μ£Όμ–΄μ Έ μžˆλ‹€. N은 2, 4, 8, 16, 32, 64, 128 쀑 ν•˜λ‚˜μ΄λ‹€.
  • μƒ‰μ’…μ΄μ˜ 각 κ°€λ‘œμ€„μ˜ μ •μ‚¬κ°ν˜•μΉΈλ“€μ˜ 색이 μœ—μ€„λΆ€ν„° μ°¨λ‘€λ‘œ λ‘˜μ§Έ 쀄뢀터 λ§ˆμ§€λ§‰ μ€„κΉŒμ§€ μ£Όμ–΄μ§„λ‹€.
  • ν•˜μ–€μƒ‰μœΌλ‘œ μΉ ν•΄μ§„ 칸은 0, νŒŒλž€μƒ‰μœΌλ‘œ μΉ ν•΄μ§„ 칸은 1둜 μ£Όμ–΄μ§€λ©°, 각 숫자 μ‚¬μ΄μ—λŠ” 빈칸이 ν•˜λ‚˜μ”© μžˆλ‹€.
  • 첫째 μ€„μ—λŠ” μž˜λΌμ§„ 햐얀색 μƒ‰μ’…μ΄μ˜ 개수λ₯Ό 좜λ ₯ν•˜κ³ , λ‘˜μ§Έ μ€„μ—λŠ” νŒŒλž€μƒ‰ μƒ‰μ’…μ΄μ˜ 개수λ₯Ό 좜λ ₯ν•œλ‹€.

아이디어

  • μ—΄κ³Ό ν–‰μ˜ μ‹œμž‘μ λΆ€ν„° λμ κΉŒμ§€ μ‚¬μ΄μ¦ˆλ§ŒνΌ λŒμ•˜μ„ λ•Œ, μ‹œμž‘μ κ³Ό ν•΄λ‹Ή μ§€μ μ˜ 값이 κ°™μ§€ μ•Šλ‹€λ©΄ ν•΄λ‹Ή μœ„μΉ˜μ˜ ν•΄λ‹Ή μ‚¬μ΄μ¦ˆ μ •μ‚¬κ°ν˜•μœΌλ‘œ 색쒅이λ₯Ό λ§Œλ“€ 수 μ—†λ‹€λŠ” λœ»μ΄λ‹€.
  • λ”°λΌμ„œ μ—΄μ˜ μ‹œμž‘μ κ³Ό ν–‰μ˜ μ‹œμž‘μ μ„ ν•¨μˆ˜ κΈ°μ€€μœΌλ‘œ 1사뢄면, 2사뢄면, 3사뢄면, 4사뢄면 μ‹œμž‘μ  κΈ°μ€€μœΌλ‘œ λ‚˜λˆ„κ³  μ›λž˜ μ‚¬μ΄μ¦ˆλ₯Ό 2λΆ„μ˜ 1λ‚Έ 크기λ₯Ό λ°”νƒ•μœΌλ‘œ DFSλ₯Ό λŒλ¦°λ‹€.
  • λ§Œμ•½ ν•΄λ‹Ή 크기둜 색쒅이λ₯Ό λ§Œλ“€ 수 μžˆλ‹€λ©΄ 첫 μ‹œμž‘ μ§€μ μ˜ 값을 νŒλ‹¨ν•΄μ„œ νŒŒλž€μƒ‰μΈμ§€ 흰색인지 κ΅¬λΆ„ν•˜μ—¬ 카운트 ν•˜κ³  returnν•œλ‹€.

κ²ͺ은 μ‹œν–‰μ°©μ˜€

  • ν‘ΈλŠ”λ° 자꾸 stackoverflowκ°€ λ‚˜μ„œ 뭐가 λ¬Έμ  μ§€ 계속 κ³ λ―Όν–ˆλ˜ 것 κ°™λ‹€.
  • DFSλ₯Ό 돌릴 λ•Œ 기저쑰건을 λͺ…ν™•νžˆ μ„€μ •ν•΄μ£Όμ§€ μ•Šμ•„ λ¬΄ν•œ DFS ν˜„μƒμ΄ λ°œμƒν•˜μ—¬ stackoverflowκ°€ λ‚¬λ˜ κ²ƒμ΄μ˜€λ‹€.
  • μ•žμœΌλ‘œ 기저쑰건을 μ’€ 더 꼼꼼히 μ„€μ •ν•˜μ—¬μ•Όκ² λ‹€...

κΈ°μ € 쑰건 잘 μ„€μ •ν•˜κΈ°...!

μ½”λ“œ

import java.io.*;
import java.util.*;

public class BOJ2630 {

    static int N;

    static int paper[][];

    static int b_cnt;
    static int w_cnt;

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

        // ν•œ λ³€μ˜ 길이
        N = Integer.parseInt(br.readLine());

        // 색쒅이가 μΉ ν•΄μ§„ λͺ¨μ–‘
        paper = new int[N][N];

        // νŒŒλž€μƒ‰ 쒅이 카운트
        b_cnt = 0;

        // ν•˜μ–€μƒ‰ 쒅이 카운트
        w_cnt = 0;

        for(int i = 0; i < N; i++){
            StringTokenizer st = new StringTokenizer(br.readLine());

            for(int j = 0; j < N; j++){
                int n = Integer.parseInt(st.nextToken());

                // μ’…μ΄μ˜ 값을 μ €μž₯ν•˜λŠ” λ°°μ—΄  에 쒅이색 μ €μž₯
                paper[i][j] = n;
            }
        }

        DFS(0, 0, N);

        System.out.println(w_cnt);
        System.out.println(b_cnt);
    }


    static public void DFS(int l, int k, int S){
        // μ •μ‚¬κ°ν˜•μœΌλ‘œ 자λ₯Ό 수 μžˆλŠ”μ§€ μ—¬λΆ€ νŒλ‹¨ λ³€μˆ˜
        boolean TF = true;

        for(int i = l; i < l + S; i++){
            for(int j = k; j < k + S; j++){
                // λ§Œμ•½ μ’…μ΄μ˜ μ‹œμž‘λΆ€λΆ„κ³Ό ν•΄λ‹Ή λΆ€λΆ„μ˜ 값이 κ°™μ§€ μ•Šλ‹€λ©΄
                if(paper[i][j] != paper[l][k]){
                    // ν•΄λ‹Ή 크기의 μ •μ‚¬κ°ν˜•μ€ 흰색, νŒŒλž€μƒ‰μœΌλ‘œ λ‚˜λ‰˜μ§€ μ•ŠλŠ”λ‹€λŠ”
                    // λœ»μ΄λ―€λ‘œ false둜 λ°”κΎΈκ³  반볡문 μ’…λ£Œ
                    TF = false;
                    break;
                }
            }
            if(!TF){
                break;
            }
        }
        // λ§Œμ•½ ν•΄λ‹Ή 크기의 μ •μ‚¬κ°ν˜•μ„ ν•œ μƒ‰κΉ”λ‘œ μΉ ν•  수 μžˆλ‹€λ©΄
        // ν•΄λ‹Ή μ •μ‚¬κ°ν˜•μ˜ μ‹œμž‘λΆ€λΆ„μ˜ 숫자λ₯Ό 확인 ν›„,
        // ν°μƒ‰μ΄λ‚˜ νŒŒλž€μƒ‰ 카운트 + 1
        if(TF){
            // μˆ«μžκ°€ 1이라면 νŒŒλž€μƒ‰ + 1
            if(paper[l][k] == 1){
                b_cnt = b_cnt + 1;
            }
            // μˆ«μžκ°€ 0이라면 흰색 + 1
            else if(paper[l][k] == 0){
                w_cnt = w_cnt + 1;
            }
        }
        // ν•΄λ‹Ή 크기의 μ •μ‚¬κ°ν˜•μœΌλ‘œ 자λ₯Ό 수 μ—†λ‹€λ©΄ 2λΆ„μ˜ 1길이둜 μž˜λΌμ„œ
        // λ‹€μ‹œ DFSλ₯Ό 돌림
        else if(!TF){
            int newS = S / 2;
            // 2사뢄면
            DFS(l, k, newS);
            // 1사뢄면
            DFS(l, k + newS, newS);
            // 3사뢄면
            DFS(l + newS, k, newS);
            // 4사뢄면
            DFS(l + newS, k + newS, newS);
        }
    }
}