파이썬 알고리즘

백준 2578 빙고 파이썬 풀이

뜻 지, 깨달음 오 2022. 9. 22. 14:50

 

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

 

2578번: 빙고

첫째 줄부터 다섯째 줄까지 빙고판에 쓰여진 수가 가장 위 가로줄부터 차례대로 한 줄에 다섯 개씩 빈 칸을 사이에 두고 주어진다. 여섯째 줄부터 열째 줄까지 사회자가 부르는 수가 차례대로

www.acmicpc.net

 

몇번째 번호를 불렀을 때 빙고가 3개 이상 완성되는지 찾는 문제이다.

MC가 번호를 불러줄때마다 해야할 일이 2가지 있다.

1) MC가 불러준 번호에 X표시하기

2) 빙고판에 빙고 몇개 생겼는지 확인하기

그래서 나는 이 두 과정을 각각의 함수에 담아서 했다.

 

 

일단 처음에 입력 데이터를 보면

11 12 2 24 10
16 1 13 3 25
6 20 5 21 17
19 4 8 14 9
22 15 7 23 18 #여기까지가 빙고판
5 10 7 16 2
4 22 8 17 13
3 18 1 6 25
12 19 23 14 21
11 24 9 20 15 #여기까지가 MC가 불러주는 숫자

빙고판은 5*5로 불러오는게 편한데

MC가 불러오는 숫자는 그냥 보기 편하게 일렬로 불러오고 싶어서 일렬로 다시 정리해줬다

(굳이 이렇게 할 필욘 없음)

bingo_board = [list(map(int, input().split())) for _ in range(5)]
temp = [list(map(int, input().split())) for _ in range(5)]

numbers_called_by_MC = []
for i in range(5):
    for j in range(5):
        numbers_called_by_MC.append(temp[i][j])

지금까지의 결과를 print 해보면

11 12 2 24 10 
16 1 13 3 25 
6 20 5 21 17 
19 4 8 14 9 
22 15 7 23 18 
[5, 10, 7, 16, 2, 4, 22, 8, 17, 13, 3, 18, 1, 6, 25, 12, 19, 23, 14, 21, 11, 24, 9, 20, 15]

 

이렇게 나온다

 

 

이제 번호가 불리면, 일단 번호의 자리에 X표시를 해줘야 한다.

나는 나중에 편하게 그냥 X표시 말고

해당 숫자를 0으로 바꿔줬다.

def find_and_change(n):
        global bingo_board
    for s in range(5):
        for t in range(5):
            if n == bingo_board[s][t]:
                bingo_board[s][t] = 0
                return

입력받은 n이 빙고보드 위의 숫자랑 같다면, 해당 숫자를 0으로 바꿔주고 함수를 끝낸다.

 

다음으로는 빙고 개수를 확인해야 한다.

def find_bingo(bingo_board):
    bingo_cnt = 0
    #가로
    for p in range(5):
        cnt_temp = 0
        for q in range(5):
            if bingo_board[p][q]==0:
                cnt_temp +=1
        if cnt_temp ==5:
            bingo_cnt +=1
    #세로
    for a in range(5):
        cnt_temp = 0
        for b in range(5):
            if bingo_board[b][a]==0:
                cnt_temp +=1
        if cnt_temp ==5:
            bingo_cnt +=1

    #대각선
    cnt_temp = 0
    for x in range(5):
        if bingo_board[x][x]==0:
            cnt_temp += 1

    if cnt_temp == 5:
        bingo_cnt +=1

    #다른대각선
    cnt_temp = 0
    for y in range(5):
        if bingo_board[y][4-y]==0:
            cnt_temp += 1

    if cnt_temp == 5:
        bingo_cnt +=1

    return bingo_cnt

cnt_temp는 각 줄마다 초기화되는 0의 개수이다.

즉, cnt_temp가 5이면 그 줄 전체가 0이라는거고, 이는 빙고가 만들어졌음을 의미한다.

bingo_cnt는 해당 빙고판에 있는 총 빙고의 개수이다.

숫자 하나를 추가할때마다 새로운 빙고판을 입력받은 후, 그 빙고판의 가로, 세로, 대각선 2개에 빙고가 있는지 확인한다.

그리고 빙고 개수를 return 한다.

 

 

MC가 불러준 숫자 25개를 하나씩 다 넣으면서, 

빙고판 숫자를 0으로 바꾸고,

빙고판의 빙고 개수를 센다

빙고 수가 3이 넘으면 넘추고, 그때 숫자가 몇번째인지 출력한다.

for k in range(25):
    find_and_change(numbers_called_by_MC[k])
    if find_bingo(bingo_board) >= 3:
        print(k+1)
        break

이때 주의할 점은

어떤 테스트케이스는 한 숫자가 0이 됨으로써 빙고가 2개가 생겨서

빙고가 2개 ->4개 로 갈 수 있다.

그러면 답이 안나온다.

==3이 아닌 >=3을 쓰자

 

그리고 파이썬의 인덱스는 0부터 시작하니까 print(k+1)을 하자

 

 

 

전체 풀이)

bingo_board = [list(map(int, input().split())) for _ in range(5)]
temp = [list(map(int, input().split())) for _ in range(5)]

numbers_called_by_MC = []
for i in range(5):
    for j in range(5):
        numbers_called_by_MC.append(temp[i][j])
# print(numbers_called_by_MC)

def find_and_change(n):
    global bingo_board
    for s in range(5):
        for t in range(5):
            if n == bingo_board[s][t]:
                bingo_board[s][t] = 0
                return

def find_bingo(bingo_board):
    bingo_cnt = 0
    #가로
    for p in range(5):
        cnt_temp = 0
        for q in range(5):
            if bingo_board[p][q]==0:
                cnt_temp +=1
        if cnt_temp ==5:
            bingo_cnt +=1
    #세로
    for a in range(5):
        cnt_temp = 0
        for b in range(5):
            if bingo_board[b][a]==0:
                cnt_temp +=1
        if cnt_temp ==5:
            bingo_cnt +=1

    #대각선
    cnt_temp = 0
    for x in range(5):
        if bingo_board[x][x]==0:
            cnt_temp += 1

    if cnt_temp == 5:
        bingo_cnt +=1

    #다른대각선
    cnt_temp = 0
    for y in range(5):
        if bingo_board[y][4-y]==0:
            cnt_temp += 1

    if cnt_temp == 5:
        bingo_cnt +=1

    return bingo_cnt

for k in range(25):
    find_and_change(numbers_called_by_MC[k])
    # print(find_bingo(bingo_board))
    if find_bingo(bingo_board) >= 3:
        print(k+1)
        break