티스토리 뷰
https://www.acmicpc.net/problem/2580
2580번: 스도쿠
스도쿠는 18세기 스위스 수학자가 만든 '라틴 사각형'이랑 퍼즐에서 유래한 것으로 현재 많은 인기를 누리고 있다. 이 게임은 아래 그림과 같이 가로, 세로 각각 9개씩 총 81개의 작은 칸으로 이루
www.acmicpc.net
일반적인 백트래킹을 이용한 스도쿠문제이다. 1 ~ 9 사이의 숫자를 넣어보고 3x3, 가로, 세로 조건을 충족하면 다음 숫자를 넣고, 충족하지 않으면 이전의 조건으로 되돌리면 된다.
시간초과 풀이
import sys
input = sys.stdin.readline
sdoku = []
for _ in range(9):
row = list(map(int, input().split()))
sdoku.append(row)
zero_point = []
for i in range(9):
for j in range(9):
if sdoku[i][j] == 0:
zero_point.append((i,j))
def check3x3(coords, val):
x, y = 3*(coords[0]//3), 3*(coords[1]//3)
for i in range(x, x+3):
for j in range(y, y+3):
if sdoku[i][j] == val:
return False
return True
def checkRow(coords, val):
row = coords[0]
for j in range(9):
if sdoku[row][j] == val:
return False
col = coords[1]
for i in range(9):
if sdoku[i][col] == val:
return False
return True
def bt(index):
if index == len(zero_point):
for i in range(9):
print(*sdoku[i])
exit(0)
for i in range(1, 10):
x = zero_point[index][0]
y = zero_point[index][1]
if check3x3((x,y), i) and checkRow((x,y), i):
sdoku[x][y] = i
bt(index+1)
sdoku[x][y] = 0
bt(0)
스도쿠 판에서 0인 점들만 탐색하는 코드인데, 0인 지점에 1 ~ 9 모든 숫자를 넣어 탐색하면 시간초과가 난다.
pypy3, python 둘 다 시간초과가 발생한다.
즉 0인 지점에 숫자를 넣기 전, 해당 지점에 넣을 수 없는 숫자들은 미리 제거하여 경우의 수를 줄여야 한다.
정답
def find_number(n,m):
nums = [1,2,3,4,5,6,7,8,9]
for i in range(9): # 가로 행 검사
if sdoku[n][i] in nums:
nums.remove(sdoku[n][i])
for j in range(9): # 세로 열 검사
if sdoku[j][m] in nums:
nums.remove(sdoku[j][m])
x_cor = (n // 3) * 3
y_cor = (m // 3) * 3
for i in range(x_cor, x_cor+3):
for j in range(y_cor, y_cor+3):
if sdoku[i][j] in nums:
nums.remove(sdoku[i][j])
# 행, 열, 3x3 까지 검사하여 0 자리에 가능한 숫자 list인 nums 반환
return nums
def bt(index):
global answer_flag
if answer_flag == True:
return
if index == len(zero_point):
for line in sdoku: # zero_point를 모두 체크한 경우 출력
print(*line)
answer_flag = True
return
i, j = zero_point[index] # 스도쿠에서 0인 좌표를 하나씩 가져온다
able_nums = find_number(i,j)
for num in able_nums:
sdoku[i][j] = num
bt(index + 1)
sdoku[i][j] = 0
보기 쉽도록 입출력 코드는 제외하였다.
위에서 시간초과 나는 코드는 1 ~ 9의 모든 숫자를 넣어보고, 그 경우에 대해 조건을 검사하였지만
시간초과를 줄인 코드는 숫자를 넣어 조건을 검사하지 않고, 미리 해당 스도쿠판에서 불가능한 숫자는 제외하고 가능한 숫자들만 후보로 뽑는다. 후보인 숫자들은 따로 조건을 검사하지 않아도 되기 때문에 시간초과를 해결할 수 있다.
pypy3만 통과가 가능하다 ㅠ
'알고리즘' 카테고리의 다른 글
[백준] 12865 평범한 배낭 - 동적계획법과 냅색(Knapsack) (0) | 2022.04.05 |
---|---|
[백준] 1463 1로만들기 - 파이썬 (0) | 2022.03.22 |
[프로그래머스] 보석 쇼핑 - 파이썬 (0) | 2022.03.13 |
카운팅 정렬 알고리즘(Counting Sort) / 계수 정렬 (0) | 2022.03.11 |
[프로그래머스] 다단계 칫솔 판매 - 파이썬 (0) | 2022.03.08 |
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- CI/CD
- jpa
- 우테코
- 환경 별 로깅 전략 분리
- Spring
- 2차 데모데이
- 5주차 회고
- ZNS
- 8주차 회고
- 3차 데모데이
- 피움
- 스프링MVC
- dm-zoned 코드분석
- 우테코 회고
- 스프링 Logback
- 런칭 페스티벌
- 네트워크
- 프로젝트
- java
- 피움 6주차 회고
- 회고
- ZNS SSD
- 스프링 프레임워크
- 알림개선기
- 스프링 부트
- 알림기능개선기
- 백준
- dm-zoned
- 팀프로젝트
- 파이썬
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
글 보관함