알고리즘/인프런: 파이썬 알고리즘 문제풀이
탐색&시뮬레이션 문제 #10. 스도쿠 검사
bearbrick
2022. 6. 1. 02:49
*이 풀이는 인프런: 파이썬 알고리즘 문제풀이 강좌에 기반하였습니다.
내 풀이
1. 행, 열, 3*3박스 별로 숫자 중복 검사를 위해서 checkRow, checkColumn, checkBox 배열을 만들고 0으로 초기화한다.
2. 위 배열의 인덱스를 스도쿠 숫자로 사용하고, 해당 인덱스의 숫자가 발견되었다면 그 배열의 값을 1로 변경한다.
3. 위 배열의 값이 1이라면, 이미 숫자가 발견되었다는 의미로 숫자가 중복된다는 것이다. 따라서 이는 스도쿠가 아니기 때문에 else문을 통해 2중 for문을 빠져나간다.
4. 이 때, 2중 for문이므로 break 한 번으로는 2중 for문을 빠져나갈 수 없으므로, forBreak 변수를 boolean으로 두어, True 및 False 값을 통해 2중 for문을 빠져나갈 수 있도록 한다.
5. 여기서 3*3 박스에서 중복이 있는 지 없는 지 확인하기 위해서, row와 col 배열을 두어 3*3 박스의 중심을 나타냈고, dx와 dy 배열을 두어 중심의 주변부를 확인할 수 있도록 했다.
6. break에 걸리지 않고 for문을 완벽히 수행했다면, 중복되는 값이 없는 스도쿠를 의미하기 때문에 "YES"를 출력한다.
import sys
#sys.stdin=open("input.txt","rt")
row=[1,1,1,4,4,4,7,7,7]
col=[1,4,7,1,4,7,1,4,7]
dx=[-1,-1,-1,0,0,0,1,1,1]
dy=[-1,0,1,-1,0,1,-1,0,1]
arr=[list(map(int, input().split())) for _ in range(9)]
checkRow=[0]*10
checkColumn=[0]*10
checkBox=[0]*10
forBreak = False
for i in range(9):
for j in range(9):
if checkRow[arr[i][j]]==0:
checkRow[arr[i][j]]=1
else:
print("NO")
forBreak = True
break
if checkColumn[arr[j][i]]==0:
checkColumn[arr[j][i]]=1
else:
print("NO")
forBreak = True
break
if checkBox[arr[row[i]+dx[j]][col[i]+dy[j]]]==0:
checkBox[arr[row[i]+dx[j]][col[i]+dy[j]]]=1
else:
print("NO")
forBreak = True
break
if forBreak:
break
checkRow=[0]*10
checkColumn=[0]*10
checkBox=[0]*10
else:
print("YES")
강사님 풀이
import sys
sys.stdin=open("input.txt","rt")
def check(a):
for i in range(9):
ch1=[0]*10 # 행 체크
ch2=[0]*10 # 열 체크
for j in range(9):
ch1[a[i][j]]=1
ch2[a[j][i]]=1
if sum(ch1)!=9 or sum(ch2)!=9:
return False
# 9개의 3*3 그룹 탐색
for i in range(3):
for j in range(3):
ch3=[0]*10
# 그룹 안의 9개 숫자 탐색
for k in range(3):
for s in range(3):
ch3[a[i*3+k][j*3+s]]=1
if sum(ch3)!=9:
return False
return True
a=[list(map(int,input().split())) for _ in range(9)]
if check(a):
print("YES")
else:
print("NO")
배운 점
1. 다중 for문을 빠져나가고 싶은 경우, 함수로 만들어서 return 을 통해 빠져나가도록 한다.