본문 바로가기

알고리즘

[백준][KOTLIN] 2630 색종이 만들기

728x90

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

 

2630번: 색종이 만들기

첫째 줄에는 전체 종이의 한 변의 길이 N이 주어져 있다. N은 2, 4, 8, 16, 32, 64, 128 중 하나이다. 색종이의 각 가로줄의 정사각형칸들의 색이 윗줄부터 차례로 둘째 줄부터 마지막 줄까지 주어진다.

www.acmicpc.net

풀이

1. 입력된 정보를 저장하는 2차원 배열을 선언하고 값을 저장한다.

2. 배열의 색이 같은 색인지 확인 한다.

3. 2번에서 같은 색일 경우 Blue 혹은 White Count 를 증가 한다.

4. 2번에서 다른 색일 경우 각 사분면에 따라 분할 한다.

5. 2번 ~ 3번 과정을 색종이가 더 이상 나누어 지지 않을 때까지 반복 한다.

코드

import java.io.*

private var whiteCnt = 0
private var blueCnt = 0
private lateinit var paper: Array<CharArray>

fun main(args: Array<String>) {
    val br = BufferedReader(InputStreamReader(System.`in`))
    val N = br.readLine().toInt()
    // 2차원 배열 입력을 받는다.
    paper = Array(N) { CharArray(N) }

    repeat(N) {
        paper[it] = br.readLine().replace(" ", "").toCharArray()
    }

    divide(0, 0, N)

    println("$whiteCnt\n$blueCnt")
    br.close()
}

private fun divide(x: Int, y: Int, n: Int) {
    // 입력된 배열의 색이 같은 지 확인 한다. 같지 않으면 나누고
    // 색이 같으면 값에 따라 Count 한다.
    if (!shouldDivide(x, y, n)) return

    val nn = n / 2
    // 각 사분면에 따라 나눈다.
    // 나눌 때 시작되는 좌표를 파라미터로 넣는다.
    divide(x, y, nn) // 1사분면
    divide(x, y + nn, nn) // 2사분면
    divide(x + nn, y, nn) // 3사분면
    divide(x + nn, y + nn, nn) // 4사분면
}

private fun shouldDivide(x: Int, y: Int, n: Int): Boolean {
    var first = paper[x][y]

    for (i in x until x + n) {
        for (j in y until y + n) {
            if (i == x && j == y) continue

            if (first != paper[i][j]) {
                return true
            }
        }
    }

    if (first == '0') whiteCnt++
    else blueCnt++
    return false
}
728x90