問題:一共有多少種不同的數獨解答呢?其中有多少種是獨立的解答呢?
如果用乙個字串來表示各種數獨,如何保證一一對應的基礎上,讓字串的長度最短?
分析:
首先要明確問題,獨立的解答到底是什麼?如何定義「獨立」這種關係?
如果任意交換數獨的兩個數字,仍然是乙個合法的數獨。
那麼我們可以定義:如果兩個數獨解答可以通過這種交換得到,則它們就不是獨立的。
假設不考慮獨立的情況下,乙個空的數獨有n個解答,那麼獨立的解答應該為 n/( 9! )。
問題一解題思路:一種用探索(heuristic)的方法估計解答總數
原理:將數獨劃分為9塊,b1、b2….b8、b9
塊行解:乙個解使得「塊行」內每行每塊恰好包含1到9
塊列解:乙個解使得「塊列」內每列每塊恰好包含1到9
標準型:12
3 456
789下面討論基於b1為標準型的「塊行解」,假設有n個,則「塊行解」總共有9!*n個。
以下的b2和b3第一行由b1的第二或第三行構成稱為「純粹型」12
3 456
789每一行的3個元素可以任意互換((3!)^6),可以任意放入6行中的一行,並且b2和b3位置可以交換。
所以共有「純粹型」:2*(3!)^6。
以下的b2和b3第一行由b1的第二或第三行混合構成稱為「混合型」12
3 456
789其中a、b、c表示1、2、3所在位置,a可以是1、2、3中任意乙個數;(3)
每行的3個元素可以任意互換;((3!)^6)
b2和b3位置可以交換;(2)
此外b2和b3的第一行共有以下9種可能:(9)||
所以共有「混合型」:3*2*9*(3!)^6
基於b1為標準型的「塊行解」有:2*(3!)^6+3*2*9*(3!)^6
總的「塊行解」有:r=9!*(2*(3!)^6+3*2*9*(3!)^6)=948 109 639 680
同理得出「塊列解」總數與「塊行解」一致,l=948 109 639 680
設每個子塊都由1到9填充的解共有g=(9!)^9
九宮格內有3個「塊行」m=r^3
設滿足「塊行」限制在滿足「子塊」限制所佔比例為k=m/g
同理滿足「塊列」限制在滿足「子塊」限制所佔比例也是一樣。
假設這兩個比例相互獨立,同時滿足「塊行列」限制在滿足「子塊」限制所佔比例約為k^2,
最後可以估算出大約總數為g*(k^2)=6.6571*10^21種。
精確結果為6.671*10^21種,已經相當接近了。
參考文獻:
問題二解題思路:
1.將數獨所有數字一一儲存,需要81byte,進一步可以壓縮為40.5byte。
2.時間換空間,只儲存8*8方陣的64個數字,其餘17個從這64個數推導出來。這樣需要32byte。
3.因為已知數獨總數約為6.7*10^21個,所有可以用k bit表示每乙個不同的數獨,k>73,這樣只需約8byte,不過這樣解碼的演算法會變得複雜很多。
擴充套件問題:
如何編碼表示乙個不完全的數獨?
我想到的是稀疏矩陣,大家有更好的方法嗎!
程式設計之美1 15 構造數獨
問題 構造乙個9 9的方格矩陣,玩家要在每個方格中,分別填上1至9的任意乙個數字,讓整個棋盤每一列 每一行以及每乙個3 3的小矩陣中的數字都不重複。首先我們通過乙個深度優先搜尋來生成乙個可行解,然後隨機刪除一定數量的數字,以生成乙個數獨。include include using namespace...
程式設計之美 1 15 構造數獨
1.15 構造數獨 數獨的棋盤,由9 9 81個小方格組成,數獨要求每一行 每一列 以及每乙個3 3的小矩陣中的數字都不重複 深度優先搜尋,回溯法 從 0,0 開始,沒有處理的呼叫函式獲取可能的取值,取乙個為當前值,搜尋下乙個個子,搜尋過程中,若出現某個格仔沒有可行值,則回溯,修改前乙個格仔的取值 ...
POJ 2676 數獨 程式設計之美1 15
演算法講解 low逼演算法dfs,這裡如果不用空間換時間會tle 所以說我們加入三個判斷矩陣 hang x i 第x行有沒有出現i lie x i 第i列有沒有出現i sq x y i 以x,y為首標號的子矩陣有沒有i 然後總結一些常見錯誤 1.每次試探成功,hang,lie,sq都要更新 2.我們...