每日刷題 解數獨

2021-09-27 03:13:54 字數 2656 閱讀 4108

編寫乙個程式,通過已填充的空格來解決數獨問題。

乙個數獨的解法需遵循如下規則:

數字 1-9 在每一行只能出現一次。

數字 1-9 在每一列只能出現一次。

數字 1-9 在每乙個以粗實線分隔的 3x3 宮內只能出現一次。

空白格用 『.』 表示。

示例:

乙個數獨。

答案被標成紅色。

note:

給定的數獨序列只包含數字 1-9 和字元 『.』 。

你可以假設給定的數獨只有唯一解。

給定數獨永遠是 9x9 形式的。

方法一:列舉法。

對於每個格仔,可以填入 1 ~ 9 個數字,共有 9 * 9 個格仔,因此一共有 9^ 種組合方法。

將上述組合方法列舉出來,選擇滿足條件的乙個即可。

上述方法雖然理論上可行,但執行時間太大,現實中不可能使用該方法。

方法二:dfs + 回溯

我們將 9 個「宮」按照以下標記劃分:

首先遍歷陣列,記錄每組/每行/每宮中已經出現的數字,並據此求出每行/每列/每宮中可以放置的數字,將其存入雜湊表中。

例如:

第一行還能放置的數字有:1,2,4,6,8,9;

第三列還能放置的數字有:1,2,3,4,5,6,7,8,9;

第一宮還能放置的數字有:1,2,4,7.

隨後開始 dfs, 對於每乙個沒有放置數字的格仔,依次檢查是否可以放置數字 1~9, 若可以放置,則放置該數字,並在對應的雜湊表中刪去該數字。若不能放置,則證明需要回溯。

例如:在上例中,對於位置 [0,3], 依照雜湊表,我們可以將 1,2,4 三個數字放入其中。

什麼時候需要回溯?

例如:

在 [0,8] 位置上, 已經無元素可放(元素 『6』 不能放在這裡,因為第 8 列/ 第 6 塊 已經存在元素 『6』),此時需要回溯。這時證明之前的放置序列並不正確,我們在此時 return 出當前函式(即返回上一層遞迴中)。

即返回到 [0,7] 位置處,對於 1 ~ 9, 已經遍歷到 『9』, 因此此處也不能放置除 『9』 以外的數字,再返回上一層。

在 [0,6] 位置處,可以放置 『8』 和 『9』, 由於 『8』 已經證明不可行,因此嘗試放置 『9』.

以上過程即回溯。

**:

class

solution

;//a 行;b 列;c 宮

for(

int i =

0; i <

9; i++

) line.

push_back

( compare)

, column.

push_back

( compare)

, block.

push_back

( compare)

;for

(int i =

0; i <

9; i++

)for

(int j =

0; j <

9; j++)if

( board[i]

[j]!=

'.')

return;}

//檢查該位置處字元是否可以放到該處

bool

check

( vector

char

>>

& board,

const

int& i,

const

int& j,

int num)

//標記

int flag =0;

//dfs + 回溯

void

dfs( vector

char

>>

& board,

int count)

int i = count /

9, j = count %9;

if( board[i]

[j]==

'.')

else

return;}

}else

dfs( board, count +1)

;return;}

void

solvesudoku

(vector

char

>>

& board)

};

**拆開看有點長且繁瑣,若把函式拿出來單獨看:

這樣就好多了(自我感覺寫的很好看,不接受反駁/批評)

數獨問題 解數獨

數獨是乙個非常有名的遊戲。整個是乙個9x9的大宮格,其中又被劃分成9個3x3的小宮格。要求在每個小格中放入1 9中的某個數字。要求是 每行 每列 每個小宮格中數字不能重複。現要求用計算機求解數獨。輸入描述 輸入9行,每行為空格隔開的9個數字,為0的地方就是需要填充的數字。輸出描述 輸出九行,每行九個...

題解 數獨 養生題

優雅的暴力 搜尋演算法小結 不過我還用了隨機化搜尋,這種搜尋思想可以防止被毒瘤出題人卡掉。有興趣的可以看一下我的一篇總結裡面寫了搜尋的一些技巧。對於實現,我的思路是.不好說,但是這樣寫搜尋又快又穩還短。以上是洛谷裝逼的話 winlere include include using namespace...

構造解數獨

public class sudoku 尋找橫座標下一位置 int findx int x,int y 尋找縱座標下一位置 int findy int x,int y 輸出完成的數獨矩陣 void sdprint system.out.print n system.out.print n 判斷當前位...