标签:
#define _CRT_SECURE_NO_WARNINGS #include<vector> #include<iostream> #include<cstring> using namespace std; struct Node { Node(int x1, int y1) :x(x1), y(y1){} int x; int y; Node* up; Node* down; Node* left; Node* right; }; class exactCover { public: vector<int> solveExactCover(); exactCover(vector<vector<bool>>&); vector<int> getAns() { return ans; } private: int M; // Number of rows int N; // Number of columns Node* mRoot; vector<Node*> mColumnLoc; vector<int> mColumnCount; vector<vector<Node*>> mNodeLoc; void cover(int); void uncover(int); vector<int> ans; bool dfs(); }; vector<vector<bool>> Suduko2ExactCover(vector<vector<int>>& a, vector<vector<int>>& list) { vector<vector<bool>> ret; int M = 0; int N = 81 * 4; for (int i = 0; i < 9; i++) for (int j = 0; j < 9; j++) { int st = 1; int en = 9; if (a[i][j]) st = en = a[i][j]; for (int k = st; k <= en; k++) { auto tmp = vector<bool>(N, false); tmp[81 * 0 + i * 9 + k - 1] = true; tmp[81 * 1 + j * 9 + k - 1] = true; tmp[81 * 2 + i * 9 + j] = true; tmp[81 * 3 + (i / 3 * 3 + j / 3) * 9 + k - 1] = true; ret.push_back(tmp); list.push_back(vector<int>{i, j, k}); } } return ret; } int main() { int T; cin >> T; while (T--) { auto a = vector<vector<int>>(9, vector<int>(9, 0)); vector<vector<int>> list; for (int i = 0; i < 9; i++) for (int j = 0; j < 9; j++) cin >> a[i][j]; auto para = Suduko2ExactCover(a, list); exactCover inst(para); inst.solveExactCover(); auto u = inst.getAns(); for (auto x : u) a[list[x][0]][list[x][1]] = list[x][2]; for (int i = 0; i < 9; i++) for (int j = 0; j < 9; j++) cout << a[i][j] << (j == 8 ? "\n" : " "); } return 0; } bool exactCover::dfs() { if (mRoot->right == mRoot) return true; auto visitedRow = vector<bool>(M, false); auto p = mRoot->right; int minC = 100000; int miny = -1; Node* minp = nullptr; while (p != mRoot) { if (mColumnCount[p->y] < minC) { minp = p; miny = p->y; minC = mColumnCount[p->y]; } p = p->right; } if (!minC || miny == -1) return false; bool solved = false; p = minp->down; cover(miny); while (p != minp) { int currentX = p->x; ans.push_back(currentX); auto q = p->right; while (q != p) { cover(q->y); q = q->right; } if (!solved) if (dfs()) return true; q = p->left; while (q != p) { uncover(q->y); q = q->left; } ans.pop_back(); p = p->down; } uncover(miny); return false; } vector<int> exactCover::solveExactCover() { dfs(); return ans; } exactCover::exactCover(vector<vector<bool>>& a) { ans.clear(); M = a.size(); if (!M) return; N = a[0].size(); mColumnLoc = vector<Node*>(N, nullptr); mColumnCount = vector<int>(N, 0); mNodeLoc = vector<vector<Node*>>(M, vector<Node*>(N, 0)); mRoot = new Node(-1, -1); vector<Node*>& cl = mColumnLoc; vector<vector<Node*>>& l = mNodeLoc; for (int i = 0; i < N; i++) cl[i] = new Node(-1, i); mRoot->right = cl[0]; mRoot->left = cl[N - 1]; for (int i = 0; i < N; i++) { cl[i]->left = (i == 0 ? mRoot : cl[i - 1]); cl[i]->right = (i == N - 1 ? mRoot : cl[i + 1]); } for (int i = 0; i < M; i++) for (int j = 0; j < N; j++) if (a[i][j]) l[i][j] = new Node(i, j); for (int j = 0; j < N; j++) { auto p = cl[j]; for (int i = 0; i < M; i++) if (a[i][j]) { mColumnCount[j]++; p->down = l[i][j]; l[i][j]->up = p; p = l[i][j]; } p->down = cl[j]; cl[j]->up = p; } for (int i = 0; i < M; i++) { Node* p = nullptr; Node* head = nullptr; for (int j = 0; j < N; j++) if (a[i][j]) { if (p == nullptr) head = p = l[i][j]; else { p->right = l[i][j]; l[i][j]->left = p; p = l[i][j]; } } p->right = head; head->left = p; } } void exactCover::cover(int X) { auto head = mColumnLoc[X]; head->left->right = head->right; head->right->left = head->left; auto p = head->down; while (p != head) { auto h1 = p; auto q = h1->right; while (q != h1) { mColumnCount[q->y]--; q->up->down = q->down; q->down->up = q->up; q = q->right; } p = p->down; } } void exactCover::uncover(int X) { auto head = mColumnLoc[X]; head->left->right = head; head->right->left = head; auto p = head->up; while (p != head) { auto h1 = p; auto q = h1->left; while (q != h1) { mColumnCount[q->y]++; q->up->down = q; q->down->up = q; q = q->left; } p = p->up; } }
dancing links
网上搜搜就有
特别要注意就是要逆向恢复
不得不说knuth的智商有点高
但是poj上的3074 TLE,我也是不服,各种贴出来说T的数据我都是秒出,算了,不理了
昨天晚上到今天纠结一个小错误
类里面的成员数据不初始化的话 有可能不是0的
就这个小错耗了N小时,让我发了两条朋友圈
标签:
原文地址:http://www.cnblogs.com/soya/p/5587620.html