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