보드게임컵에 나왔던 문제 중 하나다.
딱 봐도 이건 많은 조건 분기라는 것을 알 수 있으며, 그 조건이 무려 12가지기 때문에 구현할 때 오류 없이 잘 짜는 것이 매우 중요하다. 실수할 가능성이 매우 높기 때문에 주석(comment)으로 이 부분은 어떤 과정인지를 작성하는 것이 하나의 큰 팁이라고 본다. 실제로 이 문제를 대회에서 풀 때 주석으로 처리하면서 풀어갔음에도 3번이나 틀렸다...
결국엔 구현이 귀찮아서 그렇지, 막상 파고들면 그렇게 어려운 문제는 아니다.
먼저 이 문제는 첫 세 개의 주사위는 고정되어 있고, 나머지 두 개의 주사위 수를 무작위로 고를 수 있다. 그와 동시에 위의 12가지 족보 중 가능한 족보만으로 점수 중 최고점을 출력하면 된다. 이는 첫 번째 입력으로 주어지는 문자열을 통해 처리하면 된다.
Ones부터 Sixes, Four of a Kind, Yatch와 Choice는 구현이 간단하니 넘어가고, 핵심은 아마도 Full House, Little/Big Straight라고 생각한다. 이 셋은 구현하기 은근히 까다롭다.
이 세 가지는 집합으로 접근하여 풀었다. 굉장히 나이브(naïve)하게 짰기 때문에 이보다 더 좋은 방법이 있을 수 있음을 알린다.
- Full House는 현재 고정한 주사위를 set으로 묶고 len을 했을 때 2 이하의 수가 나온다면 그때 점수를 측정하게 했다. len의 결과가 2인 경우엔 요소가 두 개이므로 어떻게든 Full House를 만들 수 있다. 예를 들어 5가 둘, 6이 하나이건 5가 하나, 6이 둘이건 간에 55666 또는 55566을 만들 수 있다. 이런 경우에는 당연히 큰 수로 골라야 하기 때문에 두 개의 숫자 중 큰 수 × 3 + 작은 수 × 2를 고른다. 만약 len의 결과가 1이라면 나머지 두 수를 set 안의 수를 제외한 가장 큰 수로 채운다.
- Little/Big Straight는 기존의 고정된 세 개의 주사위와 각각 $ \{1, 2, 3, 4, 5\} \: $와 $ \{2, 3, 4, 5, 6\} \:$와의 교집합을 한 집합의 크기가 3일 때에만 점수를 매겼다. 왜냐하면 3이 아닌 경우에는 절대로 이 족보를 만들 수가 없기 때문이다.
이를 코드로 나타내면 아래와 같다.
import sys
if __name__ == '__main__':
zokbo = sys.stdin.readline().rstrip()
a, b, c = map(int, sys.stdin.readline().rstrip().split())
abc = [a, b, c]
set_abc = set(abc)
max_score = -1
for i in range(12):
if zokbo[i] == 'Y':
# Ones
if i == 0:
now_score = abc.count(1) + 2
max_score = max(max_score, now_score)
# Twos
elif i == 1:
now_score = abc.count(2)*2 + 4
max_score = max(max_score, now_score)
# Threes
elif i == 2:
now_score = abc.count(3)*3 + 6
max_score = max(max_score, now_score)
# Fours
elif i == 3:
now_score = abc.count(4)*4 + 8
max_score = max(max_score, now_score)
# Fives
elif i == 4:
now_score = abc.count(5)*5 + 10
max_score = max(max_score, now_score)
# Sixs
elif i == 5:
now_score = abc.count(6)*6 + 12
max_score = max(max_score, now_score)
# Four of a Kind
elif i == 6:
now_score = 0
if len(set_abc) == 2:
for now_eye in list(set_abc):
if abc.count(now_eye) == 2:
now_score = now_eye*4
elif len(set_abc) == 1:
now_score = a*4
max_score = max(max_score, now_score)
# Full House
elif i == 7:
now_score = 0
if len(set_abc) == 2:
now_score = max(set_abc)*3 + min(set_abc)*2
elif len(set_abc) == 1:
if a == 6:
now_score = 6*3 + 5*2
else:
now_score = a*3 + 6*2
max_score = max(max_score, now_score)
# Little Straight
elif i == 8:
now_score = 0
if len(set_abc & {1, 2, 3, 4, 5}) == 3:
now_score = 30
max_score = max(max_score, now_score)
# Big Straight
elif i == 9:
now_score = 0
if len(set_abc & {2, 3, 4, 5, 6}) == 3:
now_score = 30
max_score = max(max_score, now_score)
# Yatch
elif i == 10:
now_score = 0
if len(set_abc) == 1:
now_score = 50
max_score = max(max_score, now_score)
# Choice
else:
now_score = sum(abc) + 12
max_score = max(max_score, now_score)
print(max_score)
띄어쓰기(indent) 때문에 코드 길이가 길어졌을 뿐 헷갈리지 않게 코드만 잘 짠다면 충분히 쉽게 맞출 수 있다.
728x90
'Python > 백준 문제 풀이' 카테고리의 다른 글
[BOJ] 27648번 증가 배열 만들기 (0) | 2023.03.09 |
---|---|
[BOJ] 2468번 안전영역 (0) | 2023.01.29 |
[BOJ] 1331번 나이트 투어 (0) | 2023.01.14 |
[BOJ] 26517번 연속인가? ? (0) | 2023.01.07 |
[BOJ] 26069번 붙임성 좋은 총총이 (0) | 2022.12.31 |
댓글