[Baekjoon] 33011/홀수와 짝수 게임/Python/파이썬/게임이론

·2025년 2월 26일
0

문제풀이

목록 보기
39/56
post-thumbnail

💡문제

N장의 카드가 바닥에 왼쪽에서 오른쪽으로 일렬로 놓여 있다. 왼쪽에서 i번째에 위치한 카드의 앞면에는 정수 A_i가 쓰여 있다.

채완이는 희원이와 카드를 가지고 홀수와 짝수 게임을 하려고 한다. 게임의 규칙은 다음과 같다.

  1. 게임은 두 사람이 번갈아 가며 진행하며, 채완이부터 시작한다.
  2. 각 플레이어는 자신의 차례가 될 때마다 바닥에 남아있는 카드 중 한 장을 골라 들고 간다. 이때, 다음 조건을 만족하는 카드만 들고 갈 수 있다.
  • 각 플레이어가 첫 번째로 들고 갈 수 있는 카드에는 제약이 없다.
  • 이후 두 번째부터 들고 가는 카드는 반드시 자신이 첫 번째로 들고 간 카드와 홀짝 여부가 동일해야 한다.
  1. 만약 더 이상 카드를 들고 갈 수 없다면 그 플레이어가 패배한다.

채완이와 희원이가 각각 최선의 전략을 사용해 게임을 진행한다고 할 때, 게임의 승자를 구해보자.

입력

첫째 줄에 테스트 케이스의 개수 T가 주어진다. (1 <= T <= 100)
다음 줄부터 각 테스트 케이스의 정보가 주어진다. 하나의 테스트 케이스는 두 개의 줄로 이루어져 있으며, 첫째 줄에는 카드의 개수를 의미하는 정수 N이 주어진다.(1 <= N <= 100) 
둘째 줄에는 각 카드에 쓰여있는 정수 A_1, A_2, ..., A_N이 공백으로 구분되어 주어진다. (1 <= A_i <= 100)$

출력

각 테스트 케이스마다 채완이가 승리한다 amsminn, 희원이가 승리한다면 heeda0528을 한 줄에 하나씩 출력한다.

예제입력

3
4
1 2 3 4
6
1 2 3 4 5 6
5
1 2 1 3 2

예제출력

heeda0528
heeda0528
amsminn

📖내가 작성한 Code

import sys

"""
왼쪽에서부터 일렬로
채완이부터 시작 들고감
첫번째는 아무상관 없음
두번째 카드는 반드시 홀짝 같아야함
더이상 카드 들고 갈 수 없다면 그 플레이어 패배

홀수 6장 짝수 2장 일 경우
채원 홀수 희원 홀수 선택하면 희원이가 이김
"""


def count_number(array):
    odd_n, even_n = 0, 0
    for num in array:
        if num % 2 == 0:
            even_n += 1
        else:
            odd_n += 1

    if odd_n == even_n:
        return 'heeda0528'
    else:
        if max(odd_n, even_n) % 2 == 0:
            return 'heeda0528'
        else:
            return 'amsminn'


def main():
    inputs = map(int, sys.stdin.read().split())
    for _ in range(next(inputs)):
        print(count_number([next(inputs) for _ in range(next(inputs))]))


if __name__ == "__main__":
    main()


✍️풀이과정

이런 쉬운 문제의 핵심은 함정이 있다는 것. 단순보기에는 홀짝만 하면 되지 않나? 했는데 희원이가 같은 홀짝을 고르면 게임이 터짐. 항상 최선의 전략이기 때문에 이런 건 조심해야한다.


🧠 코드 리뷰

  1. 코드의 간결화 : 현재는 반복문을 통해 직접 카운팅하지만, 파이썬의 sum() 함수를 활용하면 더 간결하게 작성할 수 있습니다.

  2. 입출력 처리 개선 :

  • 입력:
    sys.stdin.read().split()으로 전체 입력을 한 번에 읽고, iter와 next()를 활용하는 방식은 빠르고 효율적입니다. 다만, 변수 이름을 it나 tokens 등으로 명시하면 읽기 쉬워집니다.
  • 출력:
    반복문마다 print()를 호출하기보다는 결과를 리스트에 저장한 후 "\n".join()으로 출력하는 방식이 조금 더 효율적입니다.
  1. 가속성 및 스타일 : PEP8 스타일 가이드에 따라 함수 사이에 두 줄의 공백을 넣고, 변수명과 함수명을 읽기 쉽게 작성하는 것이 좋습니다.

🛠️AI 개선 코드

import sys

def determine_winner(cards):
    """
    주어진 카드 리스트에서 홀수와 짝수의 개수를 계산하여 게임의 승자를 반환합니다.
    
    조건:
      - 홀수와 짝수의 개수가 같으면 'heeda0528' 승리
      - 그렇지 않은 경우, 더 많은 카드 개수가 짝수이면 'heeda0528' 승리,
        더 많은 카드 개수가 홀수이면 'amsminn' 승리
    """
    odd_count = sum(num % 2 for num in cards)
    even_count = len(cards) - odd_count

    # 홀수와 짝수의 개수가 같거나, 더 많은 쪽의 개수가 짝수일 경우 heeda0528 승리
    if odd_count == even_count or max(odd_count, even_count) % 2 == 0:
        return 'heeda0528'
    return 'amsminn'

def main():
    # 입력 데이터를 정수 리스트로 변환
    input_data = list(map(int, sys.stdin.read().split()))
    it = iter(input_data)
    t = next(it)  # 테스트 케이스 수

    results = []
    for _ in range(t):
        n = next(it)  # 카드의 개수
        cards = [next(it) for _ in range(n)]
        results.append(determine_winner(cards))
    
    # 결과 출력
    sys.stdout.write("\n".join(results))

if __name__ == "__main__":
    main()

💻결과

백준문제 보러가기


🖱️참고 링크

위키백과 게임이론

profile
우물 안에서 무언가 만드는 사람

0개의 댓글