本帖最后由 happytc 于 2012-4-17 09:05 编辑
问题很好玩,试下
为了不影响他人思路,隐藏了
**** 本内容被作者隐藏 ****
3mile 发表于 2012-4-16 15:53
大清早起来,花上点时间做下这个题
三笑,你的代码可能有问题的或效率低,当把数字多挖几个出去,就计算好久也得不到结果的
比如下面的九宫:
Local $array[9][9] = [[0, 0, 3, 8, 1, 0, 0, 0, 9], _
[5, 0, 0, 4, 0, 0, 0, 8, 0], _
[0, 6, 0, 9, 0, 0, 1, 0, 0], _
[0, 0, 8, 0, 3, 0, 0, 0, 6], _
[0, 0, 0, 0, 0, 0, 0, 0, 0], _
[9, 0, 0, 6, 0, 0, 5, 0, 0], _
[0, 0, 6, 0, 0, 9, 0, 1, 0], _
[0, 1, 0, 0, 0, 5, 0, 0, 4], _
[2, 0, 0, 0, 4, 8, 7, 0, 0]]
或者把一楼楼主给的九宫数字多挖一个,也就是把N[8][8]=6也换成0,就死在循环里出不来了
Local $array[9][9] = [[0, 6, 1, 0, 3, 0, 0, 2, 0], _
[0, 5, 0, 0, 0, 8, 1, 0, 7], _
[0, 0, 0, 0, 0, 7, 0, 3, 4], _
[0, 0, 9, 0, 0, 6, 0, 7, 8], _
[0, 0, 3, 2, 0, 9, 5, 0, 0], _
[5, 7, 0, 3, 0, 0, 9, 0, 0], _
[1, 9, 0, 7, 0, 0, 0, 0, 0], _
[8, 0, 2, 4, 0, 0, 0, 0, 0], _
[0, 4, 0, 0, 1, 0, 2, 5, 0]]
我也给个代码,方法是‘基于候选树的可能求解回溯法’:
#include <Array.au3>
Opt("MustDeclareVars", 1)
;#cs
Global $aSudoku[9][9] = [[0, 6, 1, 0, 3, 0, 0, 2, 0], _
[0, 5, 0, 0, 0, 8, 1, 0, 7], _
[0, 0, 0, 0, 0, 7, 0, 3, 4], _
[0, 0, 9, 0, 0, 6, 0, 7, 8], _
[0, 0, 3, 2, 0, 9, 5, 0, 0], _
[5, 7, 0, 3, 0, 0, 9, 0, 0], _
[1, 9, 0, 7, 0, 0, 0, 0, 0], _
[8, 0, 2, 4, 0, 0, 0, 6, 0], _
[0, 4, 0, 0, 1, 0, 2, 5, 0]]
;#ce
#cs
Global $aSudoku[9][9] = [[0, 0, 3, 8, 1, 0, 0, 0, 9], _
[5, 0, 0, 4, 0, 0, 0, 8, 0], _
[0, 6, 0, 9, 0, 0, 1, 0, 0], _
[0, 0, 8, 0, 3, 0, 0, 0, 6], _
[0, 0, 0, 0, 0, 0, 0, 0, 0], _
[9, 0, 0, 6, 0, 0, 5, 0, 0], _
[0, 0, 6, 0, 0, 9, 0, 1, 0], _
[0, 1, 0, 0, 0, 5, 0, 0, 4], _
[2, 0, 0, 0, 4, 8, 7, 0, 0]]
#ce
CoreSudoku()
Func CandidateNumber($iX, $iY, ByRef $aFlag)
Local $gi, $gj, $iCount = 0
For $i = 1 To 9
$aFlag[$i] = 0
Next
For $i = 0 To 8
$aFlag[$aSudoku[$iX][$i]] = 1
$aFlag[$aSudoku[$i][$iY]] = 1
Next
$gi = Floor($iX / 3) * 3
$gj = Floor($iY / 3) * 3
For $i = 0 To 2
For $j = 0 To 2
$aFlag[$aSudoku[$gi + $i][$gj + $j]] = 1
Next
Next
For $i = 1 To 9
If 0 == $aFlag[$i] Then $iCount += 1
Next
Return $iCount
EndFunc
Func CoreSudoku()
Local $aFlag[10], $iMinNum = 10, $iMinNumRow = -1, $iMinNumColumn
For $i = 0 To 8
For $j = 0 To 8
If $aSudoku[$i][$j] Then ContinueLoop
Local $iCandidateNum = CandidateNumber($i, $j, $aFlag)
If 0 == $iCandidateNum Then Return
If $iCandidateNum < $iMinNum Then
$iMinNumRow = $i
$iMinNumColumn = $j
$iMinNum = $iCandidateNum
EndIf
Next
Next
If -1 == $iMinNumRow Then
_ArrayDisplay($aSudoku, "Answer of sudoku is: ")
Return
EndIf
CandidateNumber($iMinNumRow, $iMinNumColumn, $aFlag)
For $i = 1 To 9
If $aFlag[$i] == 0 Then
$aSudoku[$iMinNumRow][$iMinNumColumn] = $i
CoreSudoku()
EndIf
$aSudoku[$iMinNumRow][$iMinNumColumn] = 0
Next
EndFunc
|