用深搜加回溯來實現求解數獨的所有解

2021-07-16 15:25:12 字數 1663 閱讀 6262

1.對於當前的數獨狀態,我們可以把每個未填的位置的候選數字全部找出來,可以將候選數字放到乙個陣列或在vector中

vector

find(int x, int y); //找出soudu[x][y]的候選數字

2.如果有一些未填位置的候選數字為乙個,那麼這個就是確定項,我們可以先確定填補這個位置,如果所有的未填位置的候選數字都不唯一,那麼選擇候選數字最少的那麼位置,遍歷所有的可能性

3.怎麼判斷已解出答案,以及無法繼續進行下去,要回溯前一步的狀態呢,

搜先,設計乙個 更新函式,每填補乙個位置,就更新所有的未填位置的候補數字, void update(); 其次,設計幾個全域性變數, 乙個用來判斷,當前狀態是否有更新,如果沒有更新,認定為所有的位置已經填滿,已解出答案,則輸出結果, bool can_update; 還有用bool can_continue來判斷是否存在某個未填位置沒有候選數字可填,這種情況, 無法繼續填數字 ; 另外, 在設計乙個pair

#include

#include

#include

using

namespace

std;

//初始化數獨

int soudu[9][9] = ;

//用來記錄每個位置的候選數字, index = row*9 + col

vector

pos[81];

// 記錄是否更新,若無更新,說明已填滿所有數字

bool can_update = true;

// 判斷是否還可以繼續下去,若ok=false, 那麼說明存在乙個未填位置,沒有任何候選數字

bool ok = true;

pair < int, int > chosen_item; // (chose_position, the_possible_chose_number)

int step = 0;

int sol = 0;

int is_over = false;

vector

find(int x, int y);

void update();

void print();

void sol_soudu() else

if (!ok) else

if (!is_over)

}}vector

find(int x, int y) ;

vector

ret;

for (int i = 0; i < 9; i++)

int block_row = x / 3, block_col = y / 3;

for (int i = block_row*3; i < block_row*3 + 3; i++)

for (int j = block_col * 3; j < block_col*3 + 3; j++)

for (int i = 1; i <= 9; i++) if (!a[i]) ret.push_back(i);

return ret;

}void update()

}void print()

cout

<< "-----------------------"

<< endl;

}int main()

oj 深搜 回溯(3)

求幾個數的全排列 include include using namespace std intmap 100 假設排列數的個數最多為100 int n 實際個數 int q 多少種不同的數 int icount 100 存放每種不同的數的個數。陣列大小由q決定 int itable 100 存放一...

迷宮問題(深搜 回溯)

time limit 1 sec memory limit 128 mb 64bit io format lld submit status web board 設有乙個n n 2 n 10 方格的迷宮,入口和出口分別在左上角和右上角。迷宮格仔中分別放0和1,0表示可通,1表示不能,入口和出口處肯定...

目錄 回溯與深搜

01 codeup26677 八皇后問題 02 codeup26700 n皇后問題 03 codeup23025 素數環 04 codeup26649 排列問題 05 luogu1706 全排列問題 06 luogu1157 組合的輸出 07 luogu1691 有重複元素的排列問題 08 luog...