在leetcode上偶然刷到乙個解數獨的題目:
編寫乙個程式,通過已填充的空格來解決數獨問題。
乙個數獨的解法需遵循如下規則:
note:
這個題目很是有趣,解決了數獨算不出來的難題。
首先想到的是暴力列舉了,也就是對每個空格進行列舉,回溯法。
public
void
solvesudoku
(char
board)}}
//開始回溯
bacttrack
(board, rows, cols, boxes,0,
0);}
private
boolean
bacttrack
(char
board,
boolean
rows,
boolean
cols,
boolean
boxes,
int i,
int j)
}//如果是 空 格
if(board[i]
[j]==
'.')
//如果下一步無解,回溯
board[i]
[j]=
'.';
rows[i]
[num]
=false
; cols[j]
[num]
=false
; boxes[boxindex]
[num]
=false;}
}}else
//前面都沒找到解
return
false
;}
以上的演算法便是根據給出的數獨得到數獨的解。
然後突然想試試這個演算法,但是沒有生成數獨的演算法,找到了數獨-- 乙個高效率生成數獨的演算法部落格裡的方法,也驗證了下,能達到隨機生成的效果(雖然都是偽隨機)
//seedarray是用來生成數獨的種子陣列
private
void
creatsudokuarray
(int
seedarray)
randomnum = random.
nextint(9
)+1;
}}/* 通過一維陣列和原陣列生成隨機的數獨矩陣
遍歷二維陣列裡的資料,在一維陣列找到當前值的位置,並把一維陣列
當前位置加一處位置的值賦到當前二維陣列中。目的就是將一維陣列為
依據,按照隨機產生的順序,將這個9個資料進行迴圈交換,生成乙個隨
機的數獨矩陣。
*/for(
int i =
0; i <
9; i++)}
//將生成的重新賦值給需要的,seedarray不做改變
board[i]
[j]= seedarray[i]
[j];}}
}
好了,有了生成數獨的演算法後,但是這只是個數獨終盤,還需要挖空,最後利用隨機數完成了不同等級的挖空
/**
* 給指定數獨終盤挖空,利用隨機數,隨機次數為level,也就是對每行挖level次空
* 難度對應easy--5, middle--7, hard--9
* 每次挖空後判斷是否有解,若無解重新挖空
* @param level 挖空等級
*/public
void
resetsudoku
(int level)
creatsudokuarray
(seedarray)
; random random =
newrandom()
;for
(int i =
0; i <
9; i++)}
if(!solvesudoku
(copies)
)}
好了,有了這一系列的演算法後,便可以自己寫乙個數獨遊戲了。
示意如下:
github:diyviewpracticedemo
數獨遊戲的AI解法
因為解的過程沒有全域性狀態這種概念,所以不方便使用著名的h d模板來解。其實因為格仔的數量很少,只要做簡章的優化就完全不存在問題。即使用窮舉法,也能很快算出答案。某人 不要小看窮舉法!下次準備考慮生成遊戲的演算法,難度應該較高。console工程的 sudoku.cpp 定義控制台應用程式的入口點。...
數獨解法 C 實現
include using namespace std 構造完成標誌 bool sign false 建立數獨矩陣 int num 9 9 函式宣告 void input void output bool check int n,int key int dfs int n 主函式 int main ...
數獨遊戲的深度優先遍歷解法
數獨簡介 數獨 是一種邏輯性的數字填充遊戲,玩家須以數字填進每一格,而每行 每列和每個宮 即3x3的大格 有齊1至9所有數字。遊戲設計者會提供一部份的數字,使謎題只有乙個答案。乙個已解答的數獨其實是一種多了宮的限制的拉丁方陣,因為同乙個數字不可能在同一行 列或宮中出現多於一次。深度優先遍歷演算法 學...