C++ - Sodoku Killer(DFS) - 实现一个数独解算器
文章目錄
- 數獨相關知識
- 什么是數獨
- 解題技巧
- 史上最難數獨
- 普通解法
- DFS解法
- 編寫個數獨解釋器
- 放上最難數獨來測試
- 制作到游戲
- Project
- 編譯環境
- References
以前挺喜歡玩數獨的。
覺得這些組合之間有這么“巧合”的關系,真的很神奇。
既然現在要重溫C++,那就用C++寫個數獨解算。
數獨相關知識
什么是數獨
什么是數獨,詳細可參考1。
一個好的數獨題,是只有一個解的,意思每個格子能填的數字最終是唯一的。
有一些沒有設計好的數獨題,會有多個解,也稱無解。
解題技巧
數獨技巧
我的數獨解算器就參考了里面的部分直觀法,與候選數法。
史上最難數獨
在世界最難數獨2
普通解法
數獨技巧,之前說的這個都是普通解法。
DFS解法
除了普通解法,還有DFS數獨解法,這種解法一般是用于計算機(非人類)的計算方法。
DFS了解:
- DFS數獨解法3
- DFS(深度優先搜索算法)4 - 這篇是說明與代碼都比較好
- 深度優先搜索5
因為DFS需要滲透數獨的每個數字的分支結果。
試填數字的次數會非常非常大。
最糟糕時的時間復雜度為:O(!n)。
下面代碼我是參考了:3,我將原文的代碼中添加了更詳細的注釋:
這個版本的DFS算法,只要數獨的數字位置合理的,就可以解算出來。
如果設計數獨數字初始不足17個,解算來了會有不定個解,也就是我們說的數獨無解,因為這并不數獨。
輸出:
005300000 800000020 070010500 400005300 010070006 003200080 060500009 004000030 000009700 max_deep:0 rec_count:0=== start dfs === 145327698 839654127 672918543 496185372 218473956 753296481 367542819 984761235 521839764 max_deep:82 rec_count:14578 sodoku resolved!=== end dfs ===編寫個數獨解釋器
數獨數據:
// 骨灰級難度 int arr[9][9] = {// { 0, 0, 0, 0, 0, 0, 0, 0, 0 },// C1 C2 C3 C4 C5 C6 C7 C8 C9/*R1*/ { 0, 0, 0, 0, 5, 0, 0, 9, 0 },/*R2*/ { 0, 4, 2, 0, 0, 1, 7, 5, 0 },/*R3*/ { 0, 0, 0, 9, 0, 0, 6, 0, 3 },/*R4*/ { 0, 0, 7, 3, 0, 0, 0, 0, 4 },/*R5*/ { 0, 0, 9, 0, 0, 5, 0, 0, 0 },/*R6*/ { 0, 6, 0, 0, 2, 0, 0, 0, 0 },/*R7*/ { 0, 0, 0, 0, 0, 0, 2, 1, 9 },/*R8*/ { 0, 0, 0, 0, 0, 7, 0, 0, 0 },/*R9*/ { 0, 0, 8, 1, 0, 0, 3, 0, 0 },};運行效果:
6 7 3 2 5 8 4 9 1 9 4 2 6 3 1 7 5 8 8 1 5 9 7 4 6 2 3 5 2 7 3 1 6 9 8 4 3 8 9 7 4 5 1 6 2 1 6 4 8 2 9 5 3 7 7 5 6 4 8 3 2 1 9 2 3 1 5 9 7 8 4 6 4 9 8 1 6 2 3 7 5放上最難數獨來測試
// (目前普通解題不了,只能DFS) 地獄級難度 - 世界最難數獨:https://baike.baidu.com/item/%E4%B8%96%E7%95%8C%E6%9C%80%E9%9A%BE%E6%95%B0%E7%8B%AC// 注意:====>>>> 我這個數獨程序解算不了(其實我這個程序沒有回溯處理,意思,只要是需要試填的數獨,我這個程序就可能解不了)// 只能使用DFS來解決// 這個數獨設計者是:芬蘭數學家因卡拉// 芬蘭數學家因卡拉,花費3個月時間設計出了世界上迄今難度最大的數獨游戲,而且它只有一個答案。// 因卡拉說只有思考能力最快、頭腦最聰明的人才能破解這個游戲。這是英國《每日郵報》2012年6月30日的一篇報道。// 這個號稱“世界最難數獨”的“超級游戲”,卻被揚州一位69歲的農民花三天時間解了出來,但是將第四行第二列的5改成了8。// 而這個具有初中文化的老漢,數獨游戲啟蒙正是源于揚子晚報。int arr[9][9] = {// { 0, 0, 0, 0, 0, 0, 0, 0, 0 },// C1 C2 C3 C4 C5 C6 C7 C8 C9/*R1*/ { 0, 0, 5, 3, 0, 0, 0, 0, 0 },/*R2*/ { 8, 0, 0, 0, 0, 0, 0, 2, 0 },/*R3*/ { 0, 7, 0, 0, 1, 0, 5, 0, 0 },/*R4*/ { 4, 0, 0, 0, 0, 5, 3, 0, 0 },/*R5*/ { 0, 1, 0, 0, 7, 0, 0, 0, 6 },/*R6*/ { 0, 0, 3, 2, 0, 0, 0, 8, 0 },/*R7*/ { 0, 6, 0, 5, 0, 0, 0, 0, 9 },/*R8*/ { 0, 0, 4, 0, 0, 0, 0, 3, 0 },/*R9*/ { 0, 0, 0, 0, 0, 9, 7, 0, 0 },};運行效果
145327698 839654127 672918543 496185372 218473956 753296481 367542819 984761235 521839764 max_deep:81 rec_count:14577 sodoku resolved!- max_deep 是DFS最大深度,剛好9*9=81,最大81次,剛好都遞歸過,這個數獨難度真的大。
- rec_count 是遞歸的次數,用了14577 次遞歸。
GIF運行效果:
從上圖,可以看到,我們先使用了自己的數獨解算器,然后發現解算不了,就使用DFS來解算。
制作到游戲
以前我下載過手游數獨,難度一般,最難的就專家級的。
以前玩的時候專家級大概就20~30分鐘即可解決。
有4宮,6宮,9宮格的
4宮格的比較簡單,基本都是7~9秒就可以解決。(適合小朋友入門)
6宮格的也是簡單。(適合學會入門后進階)
9宮格玩多了都覺得差不多。因為這個手游最大難度就專家級了。
后來我去網上找了一些骨灰級、至尊級,地獄級(就是我上面說的:史上最難數獨,那題)。
真的很難,需要花很長時間,雖然可以算出來,但我就沒必要玩那些了,需要助記工具太多才能完成。
其實制作好了簡單的專家級9x9數獨,基本就可以制作一款數獨游戲了,還可以提供解題提示,與記錄,方便回看解法。
然后在此基礎上還可以制作畸形數獨。
或是3D版數獨。
Project
backup :
- Sodoku_vs_2019
- Sodoku_gplusplus_2019
編譯環境
- VS2019 C++ 項目 F5即可。
- g++ 2019 項目
- 編譯常數:g++ .\Main.cpp .\PrintfCol.h .\Sodoku.cpp .\Sodoku.h .\Sodoku_Killer.cpp .\Sodoku_Killer.h -o Main
- 運行:.\Main.exe
References
百科數獨 ??
世界最難數獨 ??
數獨游戲(dfs深搜) - 這個是比較簡潔的 ?? ??
DFS(深度優先搜索算法) ??
深度優先搜索 ??
總結
以上是生活随笔為你收集整理的C++ - Sodoku Killer(DFS) - 实现一个数独解算器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 阿里云分布式调度系统-伏羲
- 下一篇: Armv6 Armv7