상세 컨텐츠

본문 제목

파이썬으로 풀어보는 백준 2580번: 스도쿠

Python/문제풀이

by 코딩하는 낙타 2020. 1. 20. 16:48

본문

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

 

2580번: 스도쿠

스도쿠는 18세기 스위스 수학자가 만든 '라틴 사각형'이랑 퍼즐에서 유래한 것으로 현재 많은 인기를 누리고 있다. 이 게임은 아래 그림과 같이 가로, 세로 각각 9개씩 총 81개의 작은 칸으로 이루어진 정사각형 판 위에서 이뤄지는데, 게임 시작 전 몇 몇 칸에는 1부터 9까지의 숫자 중 하나가 쓰여 있다. 나머지 빈 칸을 채우는 방식은 다음과 같다. 각각의 가로줄과 세로줄에는 1부터 9까지의 숫자가 한 번씩만 나타나야 한다. 굵은 선으로 구분되어 있는 3

www.acmicpc.net

 

내 풀이:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
field = [list(map(int, input().split())) for _ in range(9)]
check = [False] * 27    # 가로줄 9개, 세로줄 9게, 사각형 9개에 대한 체크리스트 27개
line_check = [False] * 10    # 0자리도 포함하여 1부터 9까지 이미 사용한 숫자를 체크하기 위한 리스트
 
while False in check:
    for i, horizontal_TF in enumerate(check[0:9]):    # horizontal_TF 는 n번 째 가로줄이 완성되있는가를 True, False로 표기
        if horizontal_TF:
            continue
 
        if field[i].count(0== 0:
            check[i] = True
            continue
 
        if field[i].count(0== 1:
            for _ in range(9):
                line_check[field[i][_]] = True
 
            field[i][field[i].index(0)] = line_check.index(False)
            check[i] = True
            line_check = [False] * 10
        else:
            pass
 
    for i, verticle_TF in enumerate(check[9:18]):   # verticle_TF 는 n번 째 세로줄이 완성되있는가를 True, False로 표기
        if verticle_TF:
            continue
        count_zero = 0
        for _ in range(9):
            if field[_][i] == 0:
                count_zero += 1
 
        if count_zero == 0:
            check[i + 9= True
            continue
 
        if count_zero == 1:
            t = 0
            for _ in range(9):
                line_check[field[_][i]] = True
                if field[_][i] != 0:
                    t += 1
                else:
                    tt = t
            field[tt][i] = line_check.index(False)
            check[i+9= True
            line_check = [False] * 10
        else:
            pass
 
    for i, square_TF in enumerate(check[18:]):    # square_TF 는 n번 째 3*3이 완성되있는가를 True, False로 표기
        if square_TF:
            continue
 
 
        count_zero = 0
        for y in range(i // 3 * 3, i // 3 * 3 + 3):
            for x in range(i % 3 * 3, i % 3 * 3 + 3):
                if field[y][x] == 0:
                    count_zero += 1
 
        if count_zero == 0:
            check[i + 18= True
            continue
 
        if count_zero == 1:
            t = 0
            for y in range(i // 3 * 3, i // 3 * 3 + 3):
                for x in range(i % 3 * 3, i % 3 * 3 + 3):
                    line_check[field[y][x]] = True
                    if field[y][x] != 0:
                        t += 1
                    else:
                        tt = t
            field[i // 3 * 3 + tt // 3][i % 3 * 3 + tt % 3= line_check.index(False)
            check[i + 18= True
            line_check = [False] * 10
 
        else:
            pass
 
for _ in range(9):
    print(" ".join([str(i) for i in field[_]]))
 

Python3, 시간 초과

가로줄, 세로줄, 사각형의 순서로 0이 존재하는가 존재하지 않는가를 기준으로 확인하였으며 한번 확인된 가로줄, 세로줄, 사각형은 다시는 확인해보지 않도록 코딩하였으나 시간이 초과하였다. 시간을 줄이는 방법은 그동안의 경험을 미루어봤을 때 2중, 3중 for문이 존재한다면 가장 안쪽에 있는 조건문을 어떠한 방법을 통해서 최대한 for문 바깥쪽으로 넘기는 것이다.

 

[문제] 만약 모든 행, 열, 혹은 사각형에서 0이 2개 이상이라면 이 알고리즘으로는 스도쿠를 완성할 수 없다.

 

다시 풀어본 스도쿠 문제

https://conak-diary.tistory.com/86

 

백준 2580번: 스도쿠

https://www.acmicpc.net/problem/2580 2580번: 스도쿠 스도쿠는 18세기 스위스 수학자가 만든 '라틴 사각형'이랑 퍼즐에서 유래한 것으로 현재 많은 인기를 누리고 있다. 이 게임은 아래 그림과 같이 가로, 세로..

conak-diary.tistory.com

 

관련글 더보기

댓글 영역