https://www.acmicpc.net/problem/2578
2578번: 빙고
첫째 줄부터 다섯째 줄까지 빙고판에 쓰여진 수가 가장 위 가로줄부터 차례대로 한 줄에 다섯 개씩 빈 칸을 사이에 두고 주어진다. 여섯째 줄부터 열째 줄까지 사회자가 부르는 수가 차례대로
www.acmicpc.net
| 1 초 | 128 MB | 19945 | 9020 | 7394 | 45.684% |
문제
빙고 게임은 다음과 같은 방식으로 이루어진다.
먼저 아래와 같이 25개의 칸으로 이루어진 빙고판에 1부터 25까지 자연수를 한 칸에 하나씩 쓴다
다음은 사회자가 부르는 수를 차례로 지워나간다. 예를 들어 5, 10, 7이 불렸다면 이 세 수를 지운 뒤 빙고판의 모습은 다음과 같다.
차례로 수를 지워가다가 같은 가로줄, 세로줄 또는 대각선 위에 있는 5개의 모든 수가 지워지는 경우 그 줄에 선을 긋는다.
이러한 선이 세 개 이상 그어지는 순간 "빙고"라고 외치는데, 가장 먼저 외치는 사람이 게임의 승자가 된다.
철수는 친구들과 빙고 게임을 하고 있다. 철수가 빙고판에 쓴 수들과 사회자가 부르는 수의 순서가 주어질 때, 사회자가 몇 번째 수를 부른 후 철수가 "빙고"를 외치게 되는지를 출력하는 프로그램을 작성하시오.
입력
첫째 줄부터 다섯째 줄까지 빙고판에 쓰여진 수가 가장 위 가로줄부터 차례대로 한 줄에 다섯 개씩 빈 칸을 사이에 두고 주어진다. 여섯째 줄부터 열째 줄까지 사회자가 부르는 수가 차례대로 한 줄에 다섯 개씩 빈 칸을 사이에 두고 주어진다. 빙고판에 쓰여진 수와 사회자가 부르는 수는 각각 1부터 25까지의 수가 한 번씩 사용된다.
출력
첫째 줄에 사회자가 몇 번째 수를 부른 후 철수가 "빙고"를 외치게 되는지 출력한다.

제출 코드1
구현하다가 막혀서 강의보고 푼 코드
# 빙고판
arr = [list(map(int, input().split())) for _ in range(5)]
# 빙고 체크
check = []
for _ in range(5):
check += map(int, input().split())
bing = [0] * 26
for i in range(5):
for j in range(5):
bing[arr[i][j]] = (i, j)
v = [[0] * 10 for _ in range(4)]
for num in check:
i, j = bing[num]
v[0][j] += 1 # 세로
v[1][i] += 1 # 가로
v[2][i-j] += 1 # 오른쪽아래
v[3][i+j] += 1 # 오른쪽 위
cnt = 0
for result in v:
cnt += result.count(5)
if cnt >= 3:
break
print(sum(v[0]))
빙고판의 가로 세로 대각, 역대각에 각각 v배열로 카운트 해주는 방식으로 풀어주셨는데.. 내가 보기엔 직관적이지 않아서 이해하는데 많은 어려움을 겪었다.
제출 코드2
깨달음을 얻고 직접 구현
# 빙고검사
def bingo():
global bingo_cnt
# 가로빙고 확인
for i in range(5):
r_cnt = 0 # 한줄에 몇개 체크?
for j in range(5):
if visited[i][j]: # True
r_cnt += 1
if r_cnt == 5:
bingo_cnt += 1
# 세로빙고 확인
for i in range(5):
c_cnt = 0 # 한줄에 몇개 체크?
for j in range(5):
if visited[j][i]: # True
c_cnt += 1
if c_cnt == 5:
bingo_cnt += 1
# 정방향 대각빙고 확인
cro_cnt = 0
for i in range(5):
if visited[i][i]: # True
cro_cnt += 1
if cro_cnt == 5:
bingo_cnt += 1
# 역방향 대각빙고 확인
xcro_cnt = 0
for i in range(5):
if visited[4-i][i]: # True
xcro_cnt += 1
if xcro_cnt == 5:
bingo_cnt += 1
# 빙고판
arr = [list(map(int, input().split())) for _ in range(5)]
# 사회자가 부르는 순서
check = []
for _ in range(5):
check += map(int, input().split())
# 빙고체크
visited = [[False] * 5 for _ in range(5)]
bingo_cnt = 0
for k in check: # 숫자
for i in range(5):
for j in range(5):
if arr[i][j] == k: # 빙고배열의 수와 사회자가 부른 수가 같을 때
visited[i][j] = True # 체크
bingo()
if bingo_cnt >= 3:
result = k
break
else:
bingo_cnt = 0 # 초기화
continue
if bingo_cnt >= 3:
break
if bingo_cnt >= 3:
break
ans = 0
for x in check:
ans += 1
if result == x:
print(ans)
break
사회자가 부르는 값을 넣는 구현이 생각보다 까다로웠고,
그 후에는 사회자가 부르는 숫자를 순서대로 부르면서 빙고판의 숫자와 대조시켜주었다.
값이 같을 때 visited를 이용해 체크를 한 후 bingo함수로 들어가서 3개이상의 빙고인지 확인해주었고,
아니라면 다시 빙고카운트값을 0으로 초기화하는 식으로 진행했다.
만약,
빙고카운트가 3이상이라면 포문을 빠져나와서 빙고카운트가 3이 될 때,
사회자가 부른 값이 몇번째인지 세어주면서 마무리 했다.
생각보다 많이 어렵다고 느껴서 내일있을 시험이 두려워지는 하루당
'알고리즘 > 백준' 카테고리의 다른 글
| 0306. [BOJ#4779] 칸토어 집합 (2) | 2024.03.06 |
|---|---|
| 0305. [BOJ#1244] 스위치 켜고 끄기 (0) | 2024.03.05 |
| 0302. [BOJ#2628] 종이 자르기 (0) | 2024.03.02 |
| 0301. [BOJ#2468] 안전영역 (0) | 2024.03.01 |
| 0228. [BOJ#2846] 오르막길 (1) | 2024.02.28 |