Algorithm/BOJ

[백준] 2578번: 빙고

뚱이, not a starfish 2024. 7. 1. 19:41
728x90

https://www.acmicpc.net/problem/2578

난이도: 실버4

▶ 문제 탐색하기

가로, 세로, 대각선으로 그을 수 있는 직선은 총 12개이다. 이중에서 3개를 택하는 조합은 12C3=220가지 이므로 경우의 수가 많지 않다.

 

◇ 입력

  1.  5X5의 빙고판을 입력받은 후, 2차원 배열로 저장한다.
  2.  사회자가 부르는 수를 1차원 배열로 저장한다.

 ◇ 원하는 출력 조건

  1.  1차원 배열에서 5개의 칸이 3번 채워지는 그 순간의 index+1을 출력한다.

▶ 코드 설계하기

 1. 위치 탐색: 사회자가 부르는 숫자가 2차원 배열의 어디에 위치해있는지 찾는다.

 2. 해당 숫자의 index를 저장한다. Q. 이차원배열로 저장할지[[ i, j ], [ i1, j2] ,..].., dict의 형태로 {''row'':col, "row2":col2,...} r고민이다. 아니면 그냥 arr[i][j] 이런 식으로 만들지..

→ marked = [[False]*5 for _ in range(5)]에서 True로 바꿔주기로 했다.

3. 아래 조건들 중 3개를 만족해야한다. 

① 대각선1: arr[0][0] ~ arr[4][4]

② 대각선2: arr[0][4] ~ arr[4][0]

③ 가로: arr[row][0] ~ arr[row][4]

④ 세로: arr[0][row] ~ arr[4][row]

▶ 회차별 수정사항

  • 지원가는 코드를 marked 2차원 행렬로 표현했다.
  • extend() 메서드를 알게 됐다.
  • enumerate() 파이썬 내장 함수에대해서 알게 되었다.

▶ 정답 코드

# 5*5 빙고 array로 입력받고 사회자가 부르는 번호
array, num = [], []
for i in range(5):
  arr = list(map(int, input().split()))
  array.append(arr)
for j in range(5):
  num.extend(map(int, input().split()))
  
# marked를 통해서 부르는 번호를 표시함
marked = [[False]*5 for _ in range(5)]
def bingo_check(marked):
  for _ in range(5):
    cnt = 0
    for i in marked:
      if all(i):
        cnt += 1
    for j in range(5):
      if all(marked[i][j] for i in range(5)):
        cnt += 1
    if all(marked[k][k] for k in range(5)):
      cnt += 1
    if all(marked[k][4-k] for k in range(5)):
      cnt += 1
    return cnt >= 3
# True로 부르는 숫자를 하나씩 지워감
for n in num:
    found = False  
    for i, row in enumerate(array):
        if n in row:
            j = row.index(n) 
            marked[i][j] = True  
            if bingo_check(marked):
                print(num.index(n) + 1) # 몇 번째 숫자로 바꿔준다.
                found = True  
                break  
    if found:
        break

 

▶ 추가 풀이

 

728x90