알고리즘/알고리즘 문제 풀이

(Python) 백준 2578번 - 빙고

용꿀 2024. 10. 3. 14:23

문제 링크: https://www.acmicpc.net/problem/2578

 

풀이

단순 구현 문제로, 우리가 빙고 게임을 실제 하는 방법을 코드로 구현하면 되는 간단한 문제이다.

 

먼저 입력받은 숫자들을 board라는 배열에 담아, 빙고판을 완성한다. 다음으로 사회자가 부르는 수들을 called_nums라는 배열에 저장한다.

사회자가 수를 하나씩 부를 때마다 숫자를 board에서 지우고(-1로 변경), 현재 board의 상태에서 몇 개의 빙고가 존재하는지 카운트한다. 그리고 카운트한 값이 3 이상이면 그때의 수가 몇 번째로 부른 숫자인지 출력하면 된다.

 

주의해야 할 점은 반드시 3 이상인지 체크해야 한다는 것이다. 빙고의 수가 정확히 3인지 체크를 하다 보니, 하나의 수에 의해 빙고가 한 번에 2개 이상 완성되는 경우가 생겨 빙고의 총개수가 4가 되는 경우는 체크할 수 없었고, 이로 인해 올바른 결과를 출력하지 못하는 경우가 있었다.

import sys

board = [] # 빙고판
called_nums = [] # 사회자가 부를 수들
length = 5

for _ in range(length):
    row = list(map(int, sys.stdin.readline().split(" ")))
    board.append(row) # 빙고판에 숫자들 입력

for _ in range(length):
    numbers = list(map(int, sys.stdin.readline().split(" ")))
    called_nums.extend(numbers) # 사회자가 부를 수들을 입력

def mark_in_board(board, num):
    for i in range(length):
        for j in range(length): # 전체 보드를 순회하며
            if board[i][j] == num: # 사회자가 부른 수가 나타나면
                board[i][j] = -1 # 이를 -1로 표시

def is_bingo(arr):
    if len(set(arr)) == 1: # 배열 내의 모든 숫자가 -1인 경우
        return True # 빙고가 하나 완성된 경우
    return False


def check_row(board): # 전체 보드에서 몇 개의 행이 빙고인지 체크
    bingo = 0
    for i in range(length):
        if is_bingo(board[i]):
            bingo += 1

    return bingo


def check_col(board): # 전체 보드에서 몇 개의 열이 빙고인지 체크
    bingo = 0
    for j in range(length):
        values = []
        for i in range(length):
            values.append(board[i][j])

        if is_bingo(values):
            bingo += 1

    return bingo


def check_diagonal(board): # 전체 보드에서 몇 개의 대각선이 빙고인지 체크
    bingo = 0

    right_down = []
    right_up = []

    for i in range(length):
        right_up.append(board[i][length-i-1])
        right_down.append(board[i][i])

    if is_bingo(right_up):
        bingo += 1

    if is_bingo(right_down):
        bingo += 1

    return bingo


def check_bingos(board): # 가로, 세로, 대각선에서 빙고의 수를 세고, 이를 반환
    row = check_row(board)
    col = check_col(board)
    diagonal = check_diagonal(board)

    return row + col + diagonal


for idx, called_num in enumerate(called_nums, 1): # 사회자가 첫 번째로 부르는 숫자부터 시작하여 끝까지 순회 
    mark_in_board(board, called_num) # 빙고판에 부르는 숫자를 체크
    
    if check_bingos(board) >= 3: # 빙고의 수가 3 이상이면
        print(idx) # 사회자가 몇 번째로 부른 숫자인지 출력하고
        break # 반복 종료