본문 바로가기

스터디 1일 1커밋

240303 [BOJ/백준] 2578. 빙고

 

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

 

2578번: 빙고

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

www.acmicpc.net


나의 코드 (스압주의)

1. 성공

# 빙고판과 빙고판과 같은 빈 빙고판 생성
arr = [list(map(int, input().split())) for _ in range(5)]
visited = [[0]*5 for _ in range(5)]

# 부르는 숫자를 2차원 배열로 생성
num = [list(map(int, input().split())) for _ in range(5)]

count = 0  # 부르는 숫자의 순서를 알기 위해 초기값 설정
flag3 = 0 # 전체적인 반복문 빠져나오기 위해 사용
for x in range(5):  # arr 범위
    for y in range(5):
        flag = 0
        for i in range(5):  # num 범위
            for j in range(5):
                if num[x][y] == arr[i][j]:  # 빙고판과 부르는 숫자가 같을 경우
                    visited[i][j] = 1       # 빙고판과 같은 빈 행렬에 1로 색칠
                    flag = 1
                    break

            if flag:
                break

        cnt = 0  # 빙고 줄 초기값 설정
        count += 1
        if count < 12:  # 빙고가 되기 위해서 3줄이 색칠이 되어 있어야 해서 부르는 숫자는 12이상이어야 함
            continue

        for r in range(5):
            sum_v = 0
            for c in range(5):
                if visited[r][c] == 1:  # 가로 탐색하면서 색칠된 곳 갯수 세기
                    sum_v += 1
                    if sum_v == 5:  # 가로 색칠된 곳이 5라면 한 줄 빙고
                        cnt += 1
                        if cnt >= 3:  # 3줄 빙고가 완성됐다면 빠져나오기
                            flag3 = 1
                            break
            if flag3:
                break
        if flag3:
            break


        for r in range(5):
            sum_v = 0
            for c in range(5):
                if visited[c][r] == 1:  # 세로 탐색하면서 색칠된 곳 갯수 세기
                    sum_v += 1
                    if sum_v == 5:  # 세로 색칠된 곳이 5라면 한 줄 빙고
                        cnt += 1
                        if cnt >= 3:  # 3줄 빙고가 완성됐다면 빠져나오기
                            flag3 = 1
                            break

            if flag3:
                break
        if flag3:
            break


        sum_v = 0
        for c in range(5):
            if visited[c][c] == 1:  # 대각선 탐색하면서 색칠된 곳 갯수 세기
                sum_v += 1
                if sum_v == 5:  # 대각선 색칠된 곳이 5라면 한 줄 빙고
                    cnt += 1
                    if cnt >= 3:  # 3줄 빙고가 완성됐다면 빠져나오기
                        flag3 = 1
                        break

        if flag3:
            break


        sum_v = 0
        for c in range(5):
            if visited[c][-(c+1)] == 1:  # 역대각선 탐색하면서 색칠된 곳 갯수 세기
                sum_v += 1
                if sum_v == 5:  # 역대각선 색칠된 곳이 5라면 한 줄 빙고
                    cnt += 1
                    if cnt >= 3:  # 3줄 빙고가 완성됐다면 빠져나오기
                        print(count)  # 그때의 숫자 출력
                        flag3 = 1
                        break

        if flag3:
            break
    if flag3:
        break

print(count)

 

2. 위 코드와 같은 거지만 실수한 부분들 주석처리한 것 포함

# 빙고판과 빙고판과 같은 빈 빙고판 생성
arr = [list(map(int, input().split())) for _ in range(5)]
visited = [[0]*5 for _ in range(5)]

# 부르는 숫자를 2차원 배열로 생성
num = [list(map(int, input().split())) for _ in range(5)]

count = 0  # 부르는 숫자의 순서를 알기 위해 초기값 설정
# cnt = 0   # 빙고 줄 초기값 설정
flag3 = 0 # 전체적인 반복문 빠져나오기 위해 사용
for x in range(5):  # arr 범위
    for y in range(5):
        flag = 0
        for i in range(5):  # num 범위
            for j in range(5):
                if num[x][y] == arr[i][j]:  # 빙고판과 부르는 숫자가 같을 경우
                    visited[i][j] = 1       # 빙고판과 같은 빈 행렬에 1로 색칠
                    flag = 1
                    break

            if flag:
                break
                
        cnt = 0  # 빙고 줄 초기값 설정
        count += 1
        if count < 12:  # 빙고가 되기 위해서 3줄이 색칠이 되어 있어야 해서 부르는 숫자는 12이상이어야 함
            continue

        # flag2 = 0
        for r in range(5):
            sum_v = 0
            for c in range(5):
                if visited[r][c] == 1:  # 가로 탐색하면서 색칠된 곳 갯수 세기
                    sum_v += 1
                    if sum_v == 5:  # 가로 색칠된 곳이 5라면 한 줄 빙고
                        cnt += 1
                        if cnt >= 3:  # 3줄 빙고가 완성됐다면 빠져나오기
                            print(count) # 그때의 숫자 출력
                            flag3 = 1
                            break
            if flag3:
                break
        if flag3:
            break


        for r in range(5):
            sum_v = 0
            for c in range(5):
                if visited[c][r] == 1:  # 세로 탐색하면서 색칠된 곳 갯수 세기
                    sum_v += 1
                    if sum_v == 5:  # 세로 색칠된 곳이 5라면 한 줄 빙고
                        cnt += 1
                        if cnt >= 3:  # 3줄 빙고가 완성됐다면 빠져나오기
                            print(count)  # 그때의 숫자 출력
                            flag3 = 1
                            break

            if flag3:
                break
        if flag3:
            break


        # for r in range(5):
        sum_v = 0
        for c in range(5):
            if visited[c][c] == 1:  # 대각선 탐색하면서 색칠된 곳 갯수 세기
                sum_v += 1
                if sum_v == 5:  # 대각선 색칠된 곳이 5라면 한 줄 빙고
                    cnt += 1
                    if cnt >= 3:  # 3줄 빙고가 완성됐다면 빠져나오기
                        print(count)  # 그때의 숫자 출력
                        flag3 = 1
                        break
           
        if flag3:
            break
    # if flag3:
    #     break


        # for r in range(5):
        sum_v = 0
        for c in range(5):
            if visited[c][-(c+1)] == 1:  # 역대각선 탐색하면서 색칠된 곳 갯수 세기
                sum_v += 1
                if sum_v == 5:  # 역대각선 색칠된 곳이 5라면 한 줄 빙고
                    cnt += 1
                    if cnt >= 3:  # 3줄 빙고가 완성됐다면 빠져나오기
                        print(count)  # 그때의 숫자 출력
                        flag3 = 1
                        break

        if flag3:
            break
    if flag3:
        break

# print(count)

 

결과


오르막길의 공포를 다시 느끼게 한 문제... 반례가 왜이렇게 많은지 하나 해결하면 다른 반례 또 생기고..ㅜㅜㅋㅋㅋㅋㅋㅋ

일단 배운 점

1. 반복문을 빠져 나오는데에 flag 한 개로 여러 반복문을 빠져 나올 수 있다는 것을 알았다.

2. 대각선과 역대각선의 인덱스는 한 개로만 가능하기에 반복문을 하나만 써도 된다.

실수한 점

1. 들여쓰기와 반복문 빠져나오는 것의 위치에 따라 결과값이 너무나도 달라진다. 이건 너무나 당연한 사실이므로 주의해서 문제를 풀어야 할 것이다.

2. 초기화도 어디서 해야 할 지 좀 더 고민해야 되겠다.

아무튼 이걸 풀어서 코드를 볼 때 어디서 빠져나가서 어디에 있는 반복문이 도는지 좀 더 잘 알 수 있게 됐다. 진짜 머리 부딪히며 성장한다는 말이 너무나 공감되는 요즘이다.