alpyrithm_알파이리즘

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

Algorithm/백준 알고리즘_Python

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

알파이 2020. 8. 4. 14:12

 

2621 카드게임    https://www.acmicpc.net/problem/2621

 

2621번: 카드게임

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

www.acmicpc.net

 

 

 

 

 

 

문제 풀기 전 공부할 것 : 수학, 구현

 

 

문제 풀기 전 주의해야 할 점 : 규칙 1 - 9까지 나와있는 입력을 넣었을 때 알맞은 출력인지 확인하면 대부분의 에러를 피할 수 있다.

 

 

 

 

 

 

 

 

 

풀이 1

<내용>

- 우선 규칙이 복잡해서 이를 정리할 필요가 있다.

- 리스트, 딕셔너리, set 등 어떤 형태로 카드 정보를 저장할 것인지 정해야 한다.

- 알아야 하는 조건이

  • 카드 5장 모두 같은 색깔인가
  • 카드 5장이 연속하는 숫자인가
  • 같은 숫자 개수

- 조건에 따라서 규칙에 따른 결과 중 가장 큰 값을 출력한다.

 

 

<코드>

cards = {}
num_cnt = [0 for _ in range(10)]
nums = set()
for _ in range(5):
    color, num = input().split()
    if color in cards:
        cards[color].append(int(num))
    else:
        cards[color] = [int(num)]
        
    num_cnt[int(num)] += 1
    nums.add(int(num))
        
nums = sorted(list(nums))

def all_same_color(cards):
    if len(cards) == 1:
        return True
    return False

def continue_num(num_cnt):
    idx = 0
    for i in range(1, 10):
        if num_cnt[i] != 1:
            if num_cnt[i] != 0:
                return False
        else:
            if idx == 0:
                idx = i
            else:
                if idx + 1 != i:
                    return False
                else:
                    idx = i
    return True
    
def cnt_same_num(num_cnt):
    cnts = sorted(num_cnt, reverse=True)
    if cnts[0] == 4:
        return 8
    elif cnts[0] == 3:
        if cnts[1] == 2:
            return 7
        else:
            return 4
    elif cnts[0] == 2:
        if cnts[1] == 2:
            return 3
        else:
            return 2
        
res = 100 + nums[-1]     
if all_same_color(cards):
    if continue_num(num_cnt):
        res = max(res, 900 + nums[-1])
    else:
        res = max(res, 600+nums[-1])
else:
    if continue_num(num_cnt):
        res = max(res, 500+nums[-1])

cnt_same_num = cnt_same_num(num_cnt)
if cnt_same_num == 8:
    res = max(res, 800+num_cnt.index(4))
elif cnt_same_num == 7:
    res = max(res, 700+10*num_cnt.index(3)+num_cnt.index(2))
elif cnt_same_num == 4:
    res = max(res, 400+num_cnt.index(3))
elif cnt_same_num == 3:
    idx1 = num_cnt.index(2)
    idx2 = num_cnt.index(2, idx1+1, 10)
    res = max(res, 300+10*idx2+idx1)
elif cnt_same_num == 2:
    res = max(res, 200+num_cnt.index(2))
    
print(res)

 

+) 구현 부분이 복잡한 것 같아서 이를 더 정리하고 규칙에 따라 함수를 만들어 해결해보려 한다.

+) 이 방법 말고 다른 방법도 분명 존재한다!

 

 

 

 

 

 

 

풀이 2

<내용>

- 규칙에 따라 나올 수 있는 점수

  • 1번 규칙을 통해 나올 수 있는 점수 : 905 - 909
  • 2번 규칙을 통해 나올 수 있는 점수 : 801 - 809
  • 3번 규칙을 통해 나올 수 있는 점수 : 711(숫자 5개 모두 1인 경우) - 799(숫자 5개 모두 9인 경우)
  • 4번 규칙을 통해 나올 수 있는 점수 : 605 - 609
  • 5번 규칙을 통해 나올 수 있는 점수 : 505 - 509
  • 6번 규칙을 통해 나올 수 있는 점수 : 401 - 409
  • 7번 규칙을 통해 나올 수 있는 점수 : 311(숫자 4개가 1인 경우) - 399(숫자 4개가 9인 경우)
  • 8번 규칙을 통해 나올 수 있는 점수 : 201 - 209
  • 9번 규칙을 통해 나올 수 있는 점수 : 101 - 109

→ 상위 규칙에 해당하면 아래 규칙을 볼 필요 없다.

 

- 상위 규칙을 만족하면 바로 return 하도록 함수 생성

- 가장 큰 숫자를 찾는 함수도 추가로 생성

 

<코드>

cards = {}
num_cnt = [0 for _ in range(10)]
for _ in range(5):
    color, num = input().split()
    if color in cards:
        cards[color].append(int(num))
    else:
        cards[color] = [int(num)]
        
    num_cnt[int(num)] += 1

def all_same_color(cards):
    if len(cards) == 1:
        return True
    return False
    
def continue_num(num_cnt):
    idx = 0
    for i in range(1, 10):
        if num_cnt[i] != 1:
            if num_cnt[i] != 0:
                return False
        else:
            if idx == 0:
                idx = i
            else:
                if idx + 1 != i:
                    return False
                else:
                    idx = i
    return True

def cnt_same_num(num_cnt):
    cnts = sorted(num_cnt, reverse=True)
    if cnts[0] == 4:
        return 8
    elif cnts[0] == 3:
        if cnts[1] == 2:
            return 7
        else:
            return 4
    elif cnts[0] == 2:
        if cnts[1] == 2:
            return 3
        else:
            return 2
        
def find_num(num_cnt, n):
    nums = []
    for i in range(9, 0, -1):
        if num_cnt[i] == n:
            nums.append(i)
    return nums

def solution(all_same, continuous, same_card, num_cnt):
    if all_same and continuous:
        return 900 + find_num(num_cnt, 1)[0]
    if same_card == 8:
        return 800 + num_cnt.index(4)
    if same_card == 7:
        return 700 + 10*num_cnt.index(3) + num_cnt.index(2)
    if all_same:
        return 600 + find_num(num_cnt, 1)[0]
    if continuous:
        return 500 + find_num(num_cnt, 1)[0]
    if same_card == 4:
        return 400 + num_cnt.index(3)
    if same_card == 3:
        nums = find_num(num_cnt, 2)
        return 300 + 10*nums[0] + nums[1]
    if same_card == 2:
        return 200 + num_cnt.index(2)
    return 100 + find_num(num_cnt, 1)[0]
        

all_same = all_same_color(cards)
continuous = continue_num(num_cnt)
same_card = cnt_same_num(num_cnt)

print(solution(all_same, continuous, same_card, num_cnt))

 

 

 

더보기

+) 견해

- 구현하기 귀찮은 문제이다.

- 규칙만 잘 정리하면 크게 어렵지 않은 문제이다.

- 어떻게 접근해서 해결하느냐에 따라 다양한 해결 방법이 나올 수 있다.

 

 

 

728x90
반응형
Comments