九宮格數獨 搜尋與剪枝

2021-10-23 05:33:01 字數 1896 閱讀 2940

這兩道題的方法基本一樣

把乙個9行9列的網格,再細分為9個3*3的子網格,要求每行、每列、每個子網格內都只能使用一次1~9中的乙個數字,即每行、每列、每個子網格內都不允許出現相同的數字。

0是待填位置,其他均為已填入的數字。

要求填完九宮格並輸出(如果有多種結果,則只需輸出其中一種)

如果給定的九宮格無法按要求填出來,則輸出原來所輸入的未填的九宮格

格仔裡面放符號/數字的問題一般都可以search(參考八數碼),不過對於數獨問題,始末狀態不確定,不能雙向bfs,a*的評估函式也比較難以確定,一般使用基本的bfs+剪枝,只要剪枝剪得好,一般都可以過。

那麼我們首先要確定bfs什麼時候結束,我們對每乙個位置x,y進行搜尋,那麼只要x=10就可以結束。然後我們要指定搜尋的策略,對每乙個位置,需要找到該行,該列,該33方格都不曾出現過的數字,行和列比較好處理,但是33方格出現的數字應該如何儲存。

即要知道第i行j列的數字是屬於哪個子網格的

首先我們假設子網格的序號如下編排:

由於1<=i、j<=9,我們有: (其中「/」是c++中對整數的除法)

令a= i/3 , b= j/3 ,根據九宮格的 行列 與 子網格 的 關係,我們有:

不難發現 3a+

b=k3a+b=k

3a+b=k

即 3∗(i

/3)+

j/3=

k3*(i/3)+j/3=k

3∗(i/3

)+j/

3=k

九宮格問題再難的話,可能就是這道題了,此時如果我們繼續dfs就會tle,因此我們需要更強的演算法,

乙個比較顯然的事實是,在你玩數獨的時候一般思路肯定是先把能確定的填上,比如樣例一,第8行第8列,那個位置可能填的數特別少。

基於這種思路,我們先從容易確定的地方dfs,下一步走到下乙個最容易確定的點,這樣解答樹能少列舉很多。

怎樣判斷乙個點的確定度呢?當然是看看它的行填上了幾個、列填上了幾個、宮填上了幾個了。

#include

#include

#include

#include

#include

using

namespace std;

#define max 15

#define ll int

#define inf 1e9

ll row[max]

[max]

, col[max]

[max]

, grid[max]

[max]

, a[max]

[max]

;bool

dfs(ll x, ll y)

else}}

return

false

;//這裡別忘了,所有數字都填不成

}int

main()

dfs(0,

0);for

(int j =

0; j <

9; j++

) cout << endl;}}

}

數獨 九宮格 破解

說到數獨,或者九宮格,我想大家一定都不陌生,初中高中看的各種雜誌上都有這種益智遊戲,現在的智慧型手機上也有人寫出了這種遊戲,閒暇時候玩玩也能活躍一下腦子。還有看 模仿遊戲 這部電影裡面,圖靈在選拔隊友的時候好像出的也是數獨的題目。我本來對數獨不是太感興趣,但是乙個偶然的機會看到朋友在玩這個遊戲,就想...

九宮格數獨遊戲

乙個九宮格數獨遊戲,以下是思路和html檔案,由於水平有限沒有使用什麼比較高階的語法,都是一些基礎的東西,所以 比較長。思路是把數獨理解成乙個二維陣列,只要每次遊戲開始隨機生成乙個符合九宮格規則的9 9二維陣列即可。如果不隨機就可以記答案,遊戲就沒意思了 1.1輸入原型陣列,這個陣列要符合規則 1....

數獨遊戲九宮格

初步定義 使用資料結構的方式實現九宮格數獨遊戲 include stdio.h 標準輸入輸出標頭檔案 include conio.h 包含getch 的標頭檔案 include stdlib.h 包含rand 的標頭檔案 include assert.h 包含assert 的標頭檔案 include...