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