c 舞蹈鏈演算法求解數獨問題 控制台版本 帶注釋

2021-10-23 04:43:17 字數 2943 閱讀 8971

#include #include #include #include #define delpointer(p) if(nullptr!=(p))

#define do(sth) for (dlxnode * pcol = prow->right; pcol != prow; pcol = pcol->right)

using namespace std;

int ans[1000];

unordered_mapm;

struct elemtype

};struct dlxnode

};class dlx

inline int getmincolpos(); // 獲取當前所有列中元素個數最小的一列

private:

int m_nindex; // 有多少個節點

int m_nrowcount; // 行數

int m_ncolcount; // 列數

int * m_psz; // 每一列有多少個節點

dlxnode *m_phead; // 頭結點(入口)

dlxnode *m_prows, *m_pcols; // 行指標與列指標

dlxnode *m_pnodes; // 所有的節點

};dlx::dlx(const int & _row, const int & _col)

dlx::dlx(const vector> & mtx)

} }}dlx::~dlx(void)

inline void dlx::addnode(const int & x, const int & y)

inline dlxnode* dlx::getnode(const int & index)

inline void dlx::deleteud(dlxnode * p)

inline void dlx::deletelr(dlxnode * p)

inline void dlx::resumeud(dlxnode * p)

inline void dlx::resumelr(dlxnode * p)

void dlx::cover(const int & col)

// 先刪除當前列的頭結點

deletelr(&m_pcols[col]);

// 找到當前列的所有node

for (dlxnode * pcol = m_pcols[col].down; pcol != &m_pcols[col]; pcol = pcol->down)

// 找到這一行與當前node相連的node,然後刪除這一行

for (dlxnode * prow = pcol->left; prow != pcol; prow = prow->left)

--m_psz[prow->elem.c];

deleteud(prow);

} deletelr(pcol); }}

void dlx::uncover(const int & col)

for (dlxnode * pcol = m_pcols[col].down; pcol != &m_pcols[col]; pcol = pcol->down)

resumelr(pcol);

for (dlxnode * prow = pcol->left; prow != pcol; prow = prow->left)

++m_psz[prow->elem.c];

resumeud(prow);

} }resumelr(&m_pcols[col]);

}bool dlx::dance(const int & step)

cout << m[ans[i] + 1] << ' ';

} return true;

} int col = getmincolpos();

/* 刪掉這一列 */

cover(col);

for (dlxnode * prow = m_pcols[col].down; prow != &m_pcols[col]; prow = prow->down)

/* 恢復這一列對應的(所有行的節點(所在的列)) */

do(uncover);

/* 連線迴圈鍊錶 */

prow->left->right = prow->right;

} /* 恢復這一列 */

uncover(col);

return false;

}void dlx::init(const int & row, const int & col)

else

/* 行指標初始化時左右指標指向自己,並且因為是前插,所有要倒序遍歷 */

for (int i = row - 1; i >= 0; --i) }}

inline int dlx::getmincolpos()

} return col;

}int main()

} }int row = cnt + (81 - cnt) * 9;

int col = 324;

cnt = 0;

dlx dlx(row, col);

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

else

}} }

if (!dlx.dance(0))

return 0;}/*

9 97 6 0 5 9 3 0 0 0

9 0 1 0 0 0 5 0 0

0 3 0 4 0 0 0 9 0

1 0 8 0 2 0 0 0 4

4 0 0 3 0 9 0 0 1

2 0 0 0 1 0 6 0 9

0 8 0 0 0 6 0 2 0

0 0 4 0 0 0 8 0 7

0 0 0 7 8 5 0 1 0

*/

舞蹈鏈(Dancing Links)演算法求解數獨

利用舞蹈鏈 dancing links 演算法求解數獨問題,實際上就是下面乙個流程 1 把數獨問題轉換為精確覆蓋問題 2 設計出資料矩陣 3 用舞蹈鏈 dancing links 演算法求解該精確覆蓋問題 4 把該精確覆蓋問題的解轉換為數獨的解 首先看看數獨問題 9 9的方格 的規則 1 每個格仔只...

DFS求解數獨演算法

以前也想過很久解數獨的演算法,但是沒有得到很簡單的方法,某天看到某位學長的 恍然大悟,本以為暴力搜尋會很花時間 10 81種可能 沒想到實際上由於各種限制,列舉次數竟然普遍小於10000次,用dfs便可實現每種可能都列舉。這樣計算乙個數獨就很快了 不到1ms 下面附上自己理解改動並加了注釋的 dev...

解數獨演算法 C 實現

時間比較倉促,未優化。大牛看客,勿笑話。當然有好的建議,我洗耳恭聽。若有時間再用mfc寫乙個介面。好了,廢話不多說,如下 include using namespace std 可選數字 int candidate 標記這個空格是否為原始資料 int g a 9 9 列印函式 void print ...