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

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


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


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

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

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

想體驗的可以去歐泊顆(http://www.oubk.com/)感受一下。


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


以下正文:

首先來回顧一下經典數獨是怎麼轉換成一個324列的精確覆蓋問題的,見《DLX算法及應用(一)DLX模板+解數獨》(http://blog.csdn.net/bl0ss0m/article/details/17918705


那麼殺手數獨就是在經典數獨的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,給我加點資源分吧^_^


下載地址:

殺手數獨例題及程序:

http://download.csdn.net/detail/u012453913/6924545

源代碼:

http://download.csdn.net/detail/u012453913/6925003













發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章