[백준] 탄소 화합물 (1907)(kotlin)

문제 설명

백준 1907번 문제 링크

입력 및 출력

» 입력

첫째 줄에 M1+M2=M3 형태의 화학식이 입력으로 주어진다. 주어지는 화학식의 길이는 50을 넘지 않으며, ‘C’, ‘H’, ‘O’, ‘+’, ‘=’와 ‘2’∼’9’만으로 이루어져 있다.

» 출력

첫째 줄에 세 정수 X1, X2, X3 (1 이상 10 이하)를 빈 칸을 사이에 두고 순서대로 출력한다. 이는 각각 M1, M2, M3의 계수가 된다. 만일 해가 둘 이상이라면 답을 세 자연수로 이루어진 수열으로 생각해서, 사전순으로 가장 앞선 것을 출력한다. (즉 X1이 가장 작은 것을 먼저 출력하고, 그것도 둘 이상이면 X2가 가장 작은 것, … 이런 순서로 출력한다.)

예제 입출력(테스트케이스)

입력 출력
C+CC=CCCCC 1 2 1
HO3H2+O=H2O2O2 2 6 3

문제 풀이1

fun main(args: Array<String>) = with(System.`in`.bufferedReader()) {
    val (a, b) = readLine().split("=")
    // 좌항과 우항에서 x1, x2, x3를 추출함
    val (x1, x2) = a.split("+").map { spliter(it) }
    val x3 = spliter(b)


    for (i in 1..10) {
        // x1에 계수 i를 곱
        val v1 = x1.map { it * i }

        for (j in 1..10) {
            // x2에 계수 j를 곱
            val v2 = x2.map { it * j }
            // 계수가 곱해진 x1과 x2를 더해 tmp로 만듬
            val tmp = IntArray(26) { v1[it] + v2[it] }

            for (k in 1..10) {
                // x3에 계수 k를 곱
                val v3 = IntArray(26) { x3[it] * k }

                // 각 계수(i, j)가 곱해서 더해진 tmp와 우항(x3)에 계수 k가 곱해진 v3가 같은지 비교
                if (isSame(tmp, v3)) {
                    // 모든 계수가 일치하면,
                    // 각 계수 i, j, k를 출력하고 프로그램 종료
                    println("$i $j $k")
                    return
                } else {
                    // 모든 계수가 일치하지 않으면,
                    // tmp의 모든 계수보다 v3 계수가 큰지를 확인 후
                    // v3가 크면 i와 j의 계수를 키우기 위해 가장 안쪽 반복문 탈출
                    if (isOverFactored(tmp, v3)) break
                }
            }
        }
    }
}

// 분자의 계수를 추출하여 IntArray로 반환
fun spliter(str: String): IntArray {
    val arr = IntArray(26) { 0 }
    val chArr = charArrayOf('C', 'H', 'O')

    for (i in str.indices) {
        if (str[i] in chArr) {
            if (i < str.length - 1) {
                if (str[i + 1] !in chArr) {
                    arr[str[i] - 'A'] += str[i + 1] - '0'
                } else {
                    arr[str[i] - 'A'] += 1
                }
            } else {
                arr[str[i] - 'A'] += 1
            }
        }
    }

    return arr
}

// 좌항과 우항에 대해 모든 원소가 각각의 계수가 동일한지 체크
fun isSame(arr1: IntArray, arr2: IntArray): Boolean {
    for (i in arr1.indices) {
        if (arr1[i] != arr2[i]) {
            return false
        }
    }

    return true
}

// 우항이 좌항보다 큰 값을 갖는지 체크
fun isOverFactored(arr1: IntArray, arr2: IntArray): Boolean {
    for (i in arr1.indices) {
        if (arr1[i] < arr2[i]) {
            return true
        }
    }

    return false
}