[백준] 탄소 화합물 (1907)(kotlin)
문제 설명
입력 및 출력
» 입력
첫째 줄에 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
}