문제 링크
27162번: Yacht Dice
《Yacht Dice》는 여러 명이 플레이하는 주사위 게임입니다. 플레이어는 우선 주사위를 5개 굴립니다. 이후 원하는 주사위를 고정시킨 뒤, 남은 주사위를 다시 굴리는 일을 두 번 이하로 할 수 있
www.acmicpc.net

문제 해설
다양한 조건 분기에 따라 조건에 맞는 계산을 수행하는 문제. Y에 해당하는 족보의 점수를 모두 계산한 후 가장 높은 값을 출력하면 된다.
이미 3개의 주사위가 고정되어 있기 때문에 나머지 2개의 주사위가 최적인 경우를 생각해볼 수 있다.
- Ones부터 Sixes까지는 나머지 2개의 주사위가 족보에서 요구하는 주사위의 눈이 나왔을 때 최대가 된다. 즉, 입력으로 주어진 고정된 주사위 중에서 (족보에 따라 1~6의 개수 + 2)×족보에 따른 수만큼 점수를 얻는다.
- 예를 들어 Ones일 경우 (입력 중 1의 개수 + 2)×1이 되고, Fives일 경우 (입력 중 5의 개수 + 2)×5가 된다.
- Four of a Kind는 나머지 2개의 주사위까지 합쳐서 같은 눈의 주사위가 4개 이상이면 된다. 즉, 고정된 주사위 중 같은 눈의 개수가 2개 이상인 수×4가 되고, 없는 경우에는 0이 된다.
- Full House부터는 고정된 주사위에서 중복을 제거한 경우를 기준으로 판단한다.
- 중복을 제거한 주사위의 개수가 1개인 경우(3개의 주사위가 모두 같은 눈인 경우)에는 주사위의 눈이 6일때와 6이 아닐 때로 나눌 수 있다.
- 3개의 주사위가 모두 6인 경우에는 6×3 + 5×2 = 28이 최대가 된다.
- 그 외의 경우에는 (고정된 주사위의 눈)×3 + 6×2가 최대가 된다.
- 중복을 제거한 주사위의 개수가 2개인 경우(2개의 주사위가 같은 눈이고 1개의 주사위가 다른 경우)에는 (둘 중 큰 수)×3 + (둘 중 작은 수)×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 |
댓글