白駿2580史都庫
白駿2580数独問題
https://www.acmicpc.net/problem/2580
Pythonコード
import sys
board = []
zero = []
row_sum = [0 for _ in range(9)]
column_sum = [0 for _ in range(9)]
rec_sum = [0 for _ in range(9)]
for i in range(9):
board.append(list(map(int, input().split())))
for i in range(9):
for v in range(9):
if board[i][v] == 0 :
zero.append([i, v])
def check(index, r, c):
number_set = {1, 2, 3, 4, 5, 6, 7, 8, 9}
for i in range(9):
if board[r][i] in number_set:
number_set.remove(board[r][i])
if board[i][c] in number_set:
number_set.remove(board[i][c])
for i in range(r - r%3 , r - r%3 +3):
for v in range(c- c%3 , c- c%3 +3):
if board[i][v] in number_set:
number_set.remove(board[i][v])
return number_set
def dfs(index, number):
global reset
if index != 0:
prev_r, prev_c = zero[index - 1]
board[prev_r][prev_c] = number
if index == len(zero):
for n in range(9):
print(" ".join(map(str, board[n])))
sys.exit()
r, c = zero[index]
for number in check(index, r, c):
board[r][c] = number
dfs(index+1, number)
board[r][c] = 0
dfs(0, 0)
解題方法
スドック問題は実現が難しくないと考えている.条件通りに記入すればいいのですが、問題はタイムアウトだと思います.
この解題プログラムは、dfsを用いて複数の場合の解題であり、数~数~数~数~数~数~数~数~数~数~数~数~数~数~数~数~数~数~数~数~数~数~数~数~数~数~数~数~数~数~数~数~数~数~数~数~数~数~数~数~数~数~数~数~数~数~数~数~数~数~数~数~数~数~数~数
疑問点
最初にスタックを使用してdfsを記述します.しかし、タイムアウトの問題が発生し続け、関連資料を探す過程で再帰関数の代わりにスタックのwhile文を使用すると、時間が少なくなります.
dfsの実装方法を上のコードのように再帰関数で実装すると,時間内に通過できる.
ではstackと再帰関数の役割は何が違うのでしょうか.
反復文VS再帰関数
逆vs順方向
半木戸では、スタックに積み上げられた数字は逆です.たとえば、ノードが到達可能な数が1、2、3、4の場合、スタックは1、2、3、4の順にスタックされ、4つの数が先に外側に出てから重複文に戻ります.
しかし、再帰関数は、あるノードが到達できる数字が1,2,3,4であれば、次の再帰は1という数字から回転します.
しかし、この違いは数独問題に大きな影響を与えるのだろうか.
もちろん、特定の問題でどの数字を先に探索するかによって、解答時間は異なりますが、問題ごとに異なるので、あまり影響はないと思います.
斯多庫条件が適切でない場合(逆追跡)
dfsを迂回する場合、sdokuの条件が適切でないため、対応するノードを削除してから戻る必要がある場合があります.
重複文を使用してdfsを実装する場合は、親ノードに戻り、数独ボードの情報を返す必要があります.あるいは、いずれの場合も、スドクパンをコピーして渡すと解決されます.
dfsを再帰関数で実現すると、サブノードが順次再帰関数を完了するにつれて、数独板が自動的に戻り、関数を終了する.
この違いは数独問題を解く上で時間的な違いが生じる!!
に感銘を与える
もちろん,コードを見たときに確認しやすく理解しやすいのは,重複文を用いたdfsである.
しかし,backtrackingに基づいてアルゴリズムを解く(タイムアウトの可能性を考慮する必要がある場合!)
より効率的なコードを記述するには、dfsおよびbacktrackingを再帰関数で実現する必要があります.
Reference
この問題について(白駿2580史都庫), 我々は、より多くの情報をここで見つけました https://velog.io/@yh20studio/백준-2580-스도쿠テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol