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...