반응형
Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
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
Archives
Today
Total
05-19 00:03
관리 메뉴

ImJay

[파이썬/Python] 백준 2621번 카드게임 본문

백준 - 문제집/대학생 기본반

[파이썬/Python] 백준 2621번 카드게임

ImJay 2023. 1. 9. 14:26
반응형

[파이썬/Python] 백준 2621번 카드게임

 

2621번: 카드게임

근우는 오늘 재미있는 카드 게임을 배우고 있다. 카드는 빨간색, 파란색, 노란색, 녹색의 네 가지 색이 있고, 색깔별로 1부터 9까지 숫자가 쓰여진 카드가 9장씩 있다. 카드는 모두 36(=4x9)장이다.

www.acmicpc.net


문제

근우는 오늘 재미있는 카드 게임을 배우고 있다. 카드는 빨간색, 파란색, 노란색, 녹색의 네 가지 색이 있고, 색깔별로 1부터 9까지 숫자가 쓰여진 카드가 9장씩 있다. 카드는 모두 36(=4x9)장이다. 근우가 배운 카드 게임은 36장의 카드에서 5장을 뽑고, 아래와 같은 규칙으로 정수를 계산하는 것이다.

각 카드는 다음과 같이 나타낸다. 카드의 색깔은 영어 대문자 R, B, Y, G로 나타내는데, R은 빨간색, B는 파란색, Y는 노란색, G는 녹색을 뜻한다. 예를 들어서 Y8은 노란색 8을 나타내고, B5는 파란색 5를 나타낸다.

<점수를 정하는 규칙>

  1. 카드 5장이 모두 같은 색이면서 숫자가 연속적일 때, 점수는 가장 높은 숫자에 900을 더한다. 예를 들어, 카드가 Y4, Y3, Y2, Y5, Y6 일 때 점수는 906(=6+900)점이다.
  2. 카드 5장 중 4장의 숫자가 같을 때 점수는 같은 숫자에 800을 더한다. 예를 들어, 카드가 B3, R3, B7, Y3, G3 일 때 점수는 803(=3+800)점이다.
  3. 카드 5장 중 3장의 숫자가 같고 나머지 2장도 숫자가 같을 때 점수는 3장이 같은 숫자에 10을 곱하고 2장이 같은 숫자를 더한 다음 700을 더한다. 예를 들어, 카드가 R5, Y5, G7, B5, Y7 일 때 점수는 757(=5x10+7+700)점이다.
  4. 5장의 카드 색깔이 모두 같을 때 점수는 가장 높은 숫자에 600을 더한다. 예를 들어, 카드가 Y3, Y4, Y8, Y6, Y7 일 때 점수는 608(=8+600)점이다.
  5. 카드 5장의 숫자가 연속적일 때 점수는 가장 높은 숫자에 500을 더한다. 예를 들어 R7, R8, G9, Y6, B5 일 때 점수는 509(=9+500)점이다.
  6. 카드 5장 중 3장의 숫자가 같을 때 점수는 같은 숫자에 400을 더한다. 예를 들어 R7, Y7, R2, G7, R5 일 때 점수는 407(=7+400)점이다.
  7. 카드 5장 중 2장의 숫자가 같고 또 다른 2장의 숫자가 같을 때 점수는 같은 숫자 중 큰 숫자에 10을 곱하고 같은 숫자 중 작은 숫자를 더한 다음 300을 더한다. 예를 들어, R5, Y5, Y4, G9, B4 일 때 점수는 354(=5X10+4+300)점이다.
  8. 카드 5장 중 2장의 숫자가 같을 때 점수는 같은 숫자에 200을 더한다. 예를 들어, R5, Y2, B5, B3, G4 일 때 점수는 205(=5+200)점이다.
  9. 위의 어떤 경우에도 해당하지 않을 때 점수는 가장 큰 숫자에 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 값에 숫자들을 리스트로 저장한다.

숫자의 수와 숫자를 저장하기 위해 리스트와 집합에 각각 따로 또 추가해준다.

 

나처럼 딕셔너리와 집합의 개념이 잘 잡혀있지 않다면 아래 글과 함께 읽으면 도움이 많이 된다.

 

02-5 딕셔너리 자료형

`[추천 동영상 강의]` : [https://www.youtube.com/watch?v=BmXDox6ZFzo](https://www.youtube.com/watch?v=BmXDo…

wikidocs.net

 

 

02-6 집합 자료형

[TOC] ## 집합 자료형은 어떻게 만들까? 집합(set)은 파이썬 2.3부터 지원하기 시작한 자료형으로, 집합에 관련된 것을 쉽게 처리하기 위해 만든 자료형이다. 집합 …

wikidocs.net

 

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 메서드는 아래의 내용을 참고하면 된다.

 

Python String index() Method

W3Schools offers free online tutorials, references and exercises in all the major languages of the web. Covering popular subjects like HTML, CSS, JavaScript, Python, SQL, Java, and many, many more.

www.w3schools.com

 

 

피드백

리스트, 딕셔너리, 집합 전부 배운 내용이지만 활용 능력이 부족했다.

조건에 대해 어떤 자료형을 어떤 메서드를 사용해야 할지 판단 능력 또한 부족하다.

기초부터 차근차근 머릿 속에 집어 넣어야겠다.

 

Reference

 

[알고리즘][Python] 백준(BOJ) 2621 카드게임_파이썬

 

alpyrithm.tistory.com

 

 

반응형
Comments