1. 程式人生 > >DLX演算法及應用(三)殺手數獨

DLX演算法及應用(三)殺手數獨

(馬上就要開學了,抽空把這個坑填上。。。。。。)

先來介紹下什麼是殺手數獨


如圖所示(來源:百度百科),殺手數獨就是在經典數獨的基礎上,又多加了一組限制條件:每一個虛線框稱作一個區,要求區內的數字不能重複,且區內數字總和等於該區左上角的數字。

殺手數獨起始是沒有一個數字的,挺難的= = 

好像在哪裡看到這樣一個提問:殺手數獨為什麼叫殺手數獨?---因為是時間的殺手。。。。。= =

正好之前在研究DLX演算法,就想試試能不能將殺手數獨轉換為一個精確覆蓋問題,網上搜了好久也沒有發現相關的資源,估計沒人這麼無聊吧= =,那我就自己試著構造一下吧。

以下正文:

那麼殺手數獨就是在經典數獨的4個限制條件基礎上,新增了一條:

虛線框內數字不重複且和為給出的數字

那麼我們就再新增405列(因為81個格子總和為405),其中將405列分成若干組,每一組就代表了一個虛線框,每一組的列數就為對應虛線框中數字之和

讓我們單獨拿出一個虛線框來考慮:

對於一個包含了{a1,a2,...,an}n個格子和為Sn的虛線框,我們令

Sn = a1+a2+...+an    (1 ≤ a1 < a2 < ... < an ≤ 9)

這樣a1最小為max{1, Sn-(n-1)(20-n)/2},最大為[Sn/n - (n-1)/2]下取整


假設其包含了3個格子,和為20,那麼它就對應了20列

可能的情況就為

3+8+9
4+7+9
5+6+9
5+7+8

這樣,任意一個格子都可能是{3,4,5,6,7,8,9}中的一個

但如果第一個格子為3,剩下2個格子就只可能為8、9

如果第一個格子為4,剩下2個格子就只可能為7、9

.....

如何用01矩陣表達這種關係呢?

再觀察下上面的4種情況,發現3、4、5只可能出現在最開始的位置,6只可能跟在5的後面,7可以跟在4或5的後面,8可以跟在3的後面,也可在最後,9只可能在最後

也就是說有1種3、4、5、6、9,2種7、8,也就是說一個格子可能為上述9種可能中的一種,那我們這樣構造:

第一個格子可能為3,前324列和經典數獨的構造方式一樣,在該虛線框對應的列組中,前3列為1

可能為4,前4列為1

可能為5,前5列為1

可能為6,第6~11列為1

可能為7(1),第5~11列為1

可能為7(2),第6~12列為1

可能為8(1),第4~11列為1

可能為8(2),第13~20列為1

可能為9,第12~20列為1

剩下的2個格子同樣如此

再舉個直觀的例子:5 = 1+4、2+3,構造的矩陣如下

...	0	...	1	...	1	0	0	0	0	...
...	0	...	1	...	1	1	0	0	0	...
...	0	...	1	...	0	0	1	1	1	...
...	0	...	1	...	0	1	1	1	1	...
...	1	...	0	...	1	0	0	0	0	...
...	1	...	0	...	1	1	0	0	0	...
...	1	...	0	...	0	0	1	1	1	...
...	1	...	0	...	0	1	1	1	1	...
前2個01列是前324列(其實是前81列)中的2列,用來確定位置,後面5列表示該虛線框

如果先選擇了第1行,那麼根據位置資訊,就會排除掉2~4行,再根據虛線框的資訊,排除掉5、6行,第7行無法完全覆蓋,所以選擇第8行,即1+4

這樣就可以構造出一個若干行,324+405列的01矩陣,再套用我們之前寫好的DLX模板,就可以快速的解決殺手數獨問題了!!

程式碼什麼的麻煩各位去下一下,所需積分0,給我加點資源分吧^_^

下載地址:

殺手數獨例題及程式:

原始碼: