일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- php
- 페이코 친구코드
- C언어
- C
- spring
- 배열
- 최단 경로
- 자바
- php 프로그래밍 입문 3판
- 자바 스프링
- php 프로그래밍
- php 프로그래밍 입문 솔루션
- Flutter
- php 프로그래밍 입문 문제풀이
- 플러터 개발환경 설정
- 플러터
- 한정 분기
- Java
- SWEA
- 백준
- JAVA SPRING
- php 프로그래밍 입문 예제
- 스프링
- 페이코 추천인코드
- 페이코 초대코드
- programmers
- php 프로그래밍 입문
- 페이코 추천인
- 파이썬
- php 프로그래밍 입문 연습문제
- Today
- Total
ImJay
[파이썬/Python] 백준 2621번 카드게임 본문
[파이썬/Python] 백준 2621번 카드게임
문제
근우는 오늘 재미있는 카드 게임을 배우고 있다. 카드는 빨간색, 파란색, 노란색, 녹색의 네 가지 색이 있고, 색깔별로 1부터 9까지 숫자가 쓰여진 카드가 9장씩 있다. 카드는 모두 36(=4x9)장이다. 근우가 배운 카드 게임은 36장의 카드에서 5장을 뽑고, 아래와 같은 규칙으로 정수를 계산하는 것이다.
각 카드는 다음과 같이 나타낸다. 카드의 색깔은 영어 대문자 R, B, Y, G로 나타내는데, R은 빨간색, B는 파란색, Y는 노란색, G는 녹색을 뜻한다. 예를 들어서 Y8은 노란색 8을 나타내고, B5는 파란색 5를 나타낸다.
<점수를 정하는 규칙>
- 카드 5장이 모두 같은 색이면서 숫자가 연속적일 때, 점수는 가장 높은 숫자에 900을 더한다. 예를 들어, 카드가 Y4, Y3, Y2, Y5, Y6 일 때 점수는 906(=6+900)점이다.
- 카드 5장 중 4장의 숫자가 같을 때 점수는 같은 숫자에 800을 더한다. 예를 들어, 카드가 B3, R3, B7, Y3, G3 일 때 점수는 803(=3+800)점이다.
- 카드 5장 중 3장의 숫자가 같고 나머지 2장도 숫자가 같을 때 점수는 3장이 같은 숫자에 10을 곱하고 2장이 같은 숫자를 더한 다음 700을 더한다. 예를 들어, 카드가 R5, Y5, G7, B5, Y7 일 때 점수는 757(=5x10+7+700)점이다.
- 5장의 카드 색깔이 모두 같을 때 점수는 가장 높은 숫자에 600을 더한다. 예를 들어, 카드가 Y3, Y4, Y8, Y6, Y7 일 때 점수는 608(=8+600)점이다.
- 카드 5장의 숫자가 연속적일 때 점수는 가장 높은 숫자에 500을 더한다. 예를 들어 R7, R8, G9, Y6, B5 일 때 점수는 509(=9+500)점이다.
- 카드 5장 중 3장의 숫자가 같을 때 점수는 같은 숫자에 400을 더한다. 예를 들어 R7, Y7, R2, G7, R5 일 때 점수는 407(=7+400)점이다.
- 카드 5장 중 2장의 숫자가 같고 또 다른 2장의 숫자가 같을 때 점수는 같은 숫자 중 큰 숫자에 10을 곱하고 같은 숫자 중 작은 숫자를 더한 다음 300을 더한다. 예를 들어, R5, Y5, Y4, G9, B4 일 때 점수는 354(=5X10+4+300)점이다.
- 카드 5장 중 2장의 숫자가 같을 때 점수는 같은 숫자에 200을 더한다. 예를 들어, R5, Y2, B5, B3, G4 일 때 점수는 205(=5+200)점이다.
- 위의 어떤 경우에도 해당하지 않을 때 점수는 가장 큰 숫자에 100을 더한다. 예를 들어, R1, R2, B4, B8, Y5 일 때 점수는 108(=8+100)점이다.
입력으로 카드 5장이 주어질 때, 카드 게임의 점수를 구하는 프로그램을 작성하시오. 두 가지 이상의 규칙을 적용할 수 있는 경우에는 가장 높은 점수가 카드 게임의 점수이다.
해설
규칙 1~9 의 조건을 차근차근 수행하여 해결할 수 있다.
코드
cards = {}
numCount = [0 for _ in range(10)]
number = set()
for _ in range(5):
color, num = input().split()
if color in cards:
cards[color].append(int(num))
else:
cards[color] = [int(num)]
numCount[int(num)] += 1
number.add(int(num))
def isSameColor(cards):
if len(cards) == 1:
return True
return False
def isContinue(numCount):
index = 0
for i in range(1, 10):
if numCount[i] != 1:
if numCount[i] != 0:
return False
else:
if index == 0:
index = i
else:
if index + 1 != i:
return False
else:
index = i
return True
def isSameNumber(numCount):
count = sorted(numCount, reverse=True)
if count[0] == 4:
return 8
elif count[0] == 3:
if count[1] == 2:
return 7
else:
return 4
elif count[0] == 2:
if count[1] == 2:
return 3
else:
return 2
number = sorted(list(number))
score = 100 + number[-1]
if isSameColor(cards):
if isContinue(numCount): # case 1
score = max(score, 900 + number[-1])
else: # case 4
score = max(score, 600 + number[-1])
else:
if isContinue(numCount): # case 5
score = max(score, 500 + number[-1])
isSameNumber = isSameNumber(numCount)
if isSameNumber == 8: # case 2
score = max(score, 800 + numCount.index(4))
elif isSameNumber == 7: # case 3
score = max(score, 700 + numCount.index(3) * 10 + numCount.index(2))
elif isSameNumber == 4: # case 6
score = max(score, 400 + numCount.index(3))
elif isSameNumber == 3: # case 7
number1 = numCount.index(2)
number2 = numCount.index(2, number1+1, 10)
score = max(score, 300 + number2*10 + number1)
elif isSameNumber == 2: # case 8
score = max(score, 200 + numCount.index(2))
print(score)
풀이
cards = {}
numCount = [0 for _ in range(10)]
number = set()
for _ in range(5):
color, num = input().split()
if color in cards:
cards[color].append(int(num))
else:
cards[color] = [int(num)]
numCount[int(num)] += 1
number.add(int(num))
1. 입력을 받는 부분이다. 딕셔너리, 집합, 리스트가 전부 사용되었다.
딕셔너리를 통해 색깔을 key 값으로, value 값에 숫자들을 리스트로 저장한다.
숫자의 수와 숫자를 저장하기 위해 리스트와 집합에 각각 따로 또 추가해준다.
나처럼 딕셔너리와 집합의 개념이 잘 잡혀있지 않다면 아래 글과 함께 읽으면 도움이 많이 된다.
def isSameColor(cards):
if len(cards) == 1:
return True
return False
2. 카드가 모두 같은 색일 경우(규칙 1, 규칙 4)를 판별하는 함수이다.
입력 받은 5장의 카드가 모두 같은 색이라면,
딕셔너리에는 { 'B' : [1,2,3,4,5] } 이런 식으로 저장되어 있을 것이다.
len 메소드의 파라미터가 딕셔너리라면 key 의 수를 반환할 것이다.
따라서 카드가 모두 같은 색이라면 1을 반환해야한다.
def isContinue(numCount):
index = 0
for i in range(1, 10):
if numCount[i] != 1:
if numCount[i] != 0:
return False
else:
if index == 0:
index = i
else:
if index + 1 != i:
return False
else:
index = i
return True
3. 카드의 숫자가 연속적인 경우(규칙 1, 규칙 5)를 판별하는 함수이다.
입력 받은 숫자의 갯수를 저장한 리스트 numCount 를 활용한다.
처음 연속이 시작되는 숫자를 index에 저장하고, 반복문을 통해 그 다음 숫자가 연속적인지 판별한다.
def isSameNumber(numCount):
count = sorted(numCount, reverse=True)
if count[0] == 4:
return 8
elif count[0] == 3:
if count[1] == 2:
return 7
else:
return 4
elif count[0] == 2:
if count[1] == 2:
return 3
else:
return 2
4. 카드의 숫자가 같은 경우(규칙 2, 규칙 3, 규칙 6, 규칙 7, 규칙 8)를 판별하는 함수이다.
마찬가지로 입력 받은 숫자의 갯수를 저장한 리스트 numCount 를 활용한다.
sorted 메소드를 통해 리스트의 값을 내림차순으로 정렬한다.(reverse = True)
만약 입력한 카드 중 4장의 숫자가 같다면, count[0] 에는 4가 저장되어 있다.
number = sorted(list(number))
score = 100 + number[-1]
if isSameColor(cards):
if isContinue(numCount): # case 1
score = max(score, 900 + number[-1])
else: # case 4
score = max(score, 600 + number[-1])
else:
if isContinue(numCount): # case 5
score = max(score, 500 + number[-1])
isSameNumber = isSameNumber(numCount)
if isSameNumber == 8: # case 2
score = max(score, 800 + numCount.index(4))
elif isSameNumber == 7: # case 3
score = max(score, 700 + numCount.index(3) * 10 + numCount.index(2))
elif isSameNumber == 4: # case 6
score = max(score, 400 + numCount.index(3))
elif isSameNumber == 3: # case 7
number1 = numCount.index(2)
number2 = numCount.index(2, number1+1, 10)
score = max(score, 300 + number2*10 + number1)
elif isSameNumber == 2: # case 8
score = max(score, 200 + numCount.index(2))
print(score)
5. 규칙에 따라 점수를 계산한다.
number 집합을 리스트로 형변환 후 오름차순으로 분리한 다음, 가장 높은 숫자를 number 리스트의 -1 인덱스를 활용한다.
파이썬의 index 메서드를 통해 같은 숫자의 카드 점수를 계산하며, case 7 과 같은 경우도 함께 해결할 수 있다.
index 메서드는 아래의 내용을 참고하면 된다.
피드백
리스트, 딕셔너리, 집합 전부 배운 내용이지만 활용 능력이 부족했다.
조건에 대해 어떤 자료형을 어떤 메서드를 사용해야 할지 판단 능력 또한 부족하다.
기초부터 차근차근 머릿 속에 집어 넣어야겠다.
Reference
'백준 - 문제집 > 대학생 기본반' 카테고리의 다른 글
[파이썬/Python] 백준 8979번 올림픽 (0) | 2023.01.16 |
---|---|
[파이썬/Python] 백준 2816번 디지털 티비 (0) | 2023.01.16 |
[파이썬/Python] 백준 1652번 누울 자리를 찾아라 (0) | 2022.12.22 |
[파이썬/Python] 백준 1747번 소수&팰린드롬 (0) | 2022.12.21 |
[파이썬/Python] 백준 대학생 기본반 (0) | 2022.12.21 |