Algorithm/BOJ
[백준] 2578번: 빙고
뚱이, not a starfish
2024. 7. 1. 19:41
728x90
https://www.acmicpc.net/problem/2578
난이도: 실버4
▶ 문제 탐색하기
가로, 세로, 대각선으로 그을 수 있는 직선은 총 12개이다. 이중에서 3개를 택하는 조합은 12C3=220가지 이므로 경우의 수가 많지 않다.
◇ 입력
- 5X5의 빙고판을 입력받은 후, 2차원 배열로 저장한다.
- 사회자가 부르는 수를 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