문제 링크
문제 해설
다양한 조건 분기에 따라 조건에 맞는 계산을 수행하는 문제. Y에 해당하는 족보의 점수를 모두 계산한 후 가장 높은 값을 출력하면 된다.
이미 3개의 주사위가 고정되어 있기 때문에 나머지 2개의 주사위가 최적인 경우를 생각해볼 수 있다.
- Ones부터 Sixes까지는 나머지 2개의 주사위가 족보에서 요구하는 주사위의 눈이 나왔을 때 최대가 된다. 즉, 입력으로 주어진 고정된 주사위 중에서 (족보에 따라 1~6의 개수 + 2)\(\times\)족보에 따른 수만큼 점수를 얻는다.
- 예를 들어 Ones일 경우 (입력 중 1의 개수 + 2)\(\times\)1이 되고, Fives일 경우 (입력 중 5의 개수 + 2)\(\times\)5가 된다.
- Four of a Kind는 나머지 2개의 주사위까지 합쳐서 같은 눈의 주사위가 4개 이상이면 된다. 즉, 고정된 주사위 중 같은 눈의 개수가 2개 이상인 수\(\times\)4가 되고, 없는 경우에는 0이 된다.
- Full House부터는 고정된 주사위에서 중복을 제거한 경우를 기준으로 판단한다.
- 중복을 제거한 주사위의 개수가 1개인 경우(3개의 주사위가 모두 같은 눈인 경우)에는 주사위의 눈이 6일때와 6이 아닐 때로 나눌 수 있다.
- 3개의 주사위가 모두 6인 경우에는 6\(\times\)3 + 5\(\times\)2 = 28이 최대가 된다.
- 그 외의 경우에는 (고정된 주사위의 눈)\(\times\)3 + 6\(\times\)2가 최대가 된다.
- 중복을 제거한 주사위의 개수가 2개인 경우(2개의 주사위가 같은 눈이고 1개의 주사위가 다른 경우)에는 (둘 중 큰 수)\(\times\)3 + (둘 중 작은 수)\(\times\)2가 최대가 된다. 큰 수가 2번 나왔을 때는 나머지 주사위에서 큰 수 1번, 작은 수 1번만 나오면 되고, 큰 수가 1번만 나왔을 때는 나머지 주사위에서 큰 수 2번이 나오면 되기 때문이다.
- 중복을 제거한 주사위의 개수가 3개인 경우(3개의 주사위가 모두 다른 경우)에는 Full House가 불가능하기 때문에 0점이 된다.
- 중복을 제거한 주사위의 개수가 1개인 경우(3개의 주사위가 모두 같은 눈인 경우)에는 주사위의 눈이 6일때와 6이 아닐 때로 나눌 수 있다.
- Little Straight는 중복을 제거한 주사위의 개수가 3개이면서 6을 포함하지 않고 있을 때 30점, 그 외의 경우엔 0점이 된다. 중복된 수가 하나라도 존재하거나 6을 포함하고 있다면 5개를 뽑았을 때 1 2 3 4 5를 뽑을 수 없기 때문이다.
- Big Straight는 마찬가지로 중복을 제거한 주사위의 개수가 3개이면서 1을 포함하지 않고 있을 때 30점, 그 외의 경우엔 0점이 된다.
- Yacht는 중복을 제거한 주사위의 개수가 1개(3개의 주사위가 모두 같은 경우)일 때 50점, 그 외엔 0점이 된다.
- Choice는 그냥 주사위의 눈의 합계 + 12를 하면 최대가 된다.
이렇게 계산한 점수 중 최대값이 정답이 된다.
Code
import java.util.StringTokenizer
fun main() = with(System.`in`.bufferedReader()) {
val pedigree = readLine()
val dice = StringTokenizer(readLine()).run { IntArray(3) { nextToken().toInt() } }
val distinctDice = dice.distinct().toIntArray()
val scores = IntArray(12)
for (i in scores.indices) {
if (pedigree[i] == 'N') continue
scores[i] = when (i) {
0 -> dice.homework(1)
1 -> dice.homework(2)
2 -> dice.homework(3)
3 -> dice.homework(4)
4 -> dice.homework(5)
5 -> dice.homework(6)
6 -> dice.calcFourOfAKind()
7 -> distinctDice.calcFullHouse()
8 -> distinctDice.calcLittleStraight()
9 -> distinctDice.calcBigStraight()
10 -> distinctDice.calcYacht()
else -> dice.sum() + 12
}
}
println(scores.max())
}
private fun IntArray.homework(n: Int) = (2 + count { it == n }) * n
private fun IntArray.calcFourOfAKind() = filter { n -> count { it == n } >= 2 }.run { if (isNotEmpty()) get(0) * 4 else 0 }
private fun IntArray.calcFullHouse() = if (size == 1) if (sum() == 6) 28 else 12 + sum() * 3 else if (size == 2) max() * 3 + min() * 2 else 0
private fun IntArray.calcLittleStraight() = if (size == 3 && !contains(6)) 30 else 0
private fun IntArray.calcBigStraight() = if (size == 3 && !contains(1)) 30 else 0
private fun IntArray.calcYacht() = if (size == 1) 50 else 0
'Algorithm > BOJ' 카테고리의 다른 글
[Kotlin] 백준 3447 : 버그왕 (0) | 2023.10.14 |
---|---|
[Kotlin] 백준 21944 : 문제 추천 시스템 Version 2 (0) | 2023.09.13 |
[Kotlin] 백준 6568 : 귀도 반 로썸은 크리스마스날 심심하다고 파이썬을 만들었다 (0) | 2023.08.31 |
[Kotlin] 백준 20551 : Sort 마스터 배지훈의 후계자 (0) | 2023.08.23 |
[Kotlin] 백준 1644 : 소수의 연속합 (0) | 2023.08.11 |
댓글