UVALive 2659 数独 DLX模板
2014-10-27 19:35
211 查看
建图:
从1到16枚举所有的行、列上放的数。
代码:
View Code
从1到16枚举所有的行、列上放的数。
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <algorithm> #include <string> #include <queue> #include <stack> #include <vector> #include <map> #include <set> #include <functional> #include <cctype> #include <time.h> using namespace std; const int INF = 1<<30; const int MAXN = 1055; const int MAXNODE = 16555; const int MAXR = 1055; struct DLX { // 行编号从1开始,列编号为1~n,结点0是表头结点;结点1~n是各列顶部的虚拟结点 int n, sz; // 列数,结点总数 int S[MAXN]; //各列结点数 int row[MAXNODE], col[MAXNODE]; //各结点行列编号 int L[MAXNODE], R[MAXNODE], U[MAXNODE], D[MAXNODE]; //十字链表 int ansd, ans[MAXR]; // 解 void init(int n) { //n是列数 this->n = n; //虚拟结点 for (int i = 0; i <= n; i++) { U[i] = i; D[i] = i; L[i] = i-1; R[i] = i+1; } R = 0; L[0] = n; sz = n+1; memset(S, 0, sizeof(S)); } void addRow(int r, vector<int> columns) { //这一行的第一个结点 //行没有设头结点,每一行连成一个环形 int first = sz; for (int i = 0; i < columns.size(); i++) { int c = columns[i]; L[sz] = sz-1; R[sz] = sz+1; D[sz] = c; U[sz] = U[c]; D[U[c]] = sz; U[c] = sz; row[sz] = r; col[sz] = c; S[c]++; sz++; } R[sz-1] = first; L[first] = sz-1; } //顺着链表A,遍历s外的其他元素 #define FOR(i, A, s) for (int i = A[s]; i != s; i = A[i]) void remove(int c) { //删除c列 L[R[c]] = L[c]; R[L[c]] = R[c]; for (int i = D[c]; i != c; i = D[i]) // 对于每一个c列不为0的所有行 for (int j = R[i]; j != i; j = R[j]) { //删除这一整行 U[D[j]] = U[j]; D[U[j]] = D[j]; S[col[j]]--; } } void restore(int c) { //回连c列 for (int i = U[c]; i != c; i = U[i]) for (int j = L[i]; j != i; j = L[j]) { U[D[j]] = j; D[U[j]] = j; S[col[j]]++; } L[R[c]] = c; R[L[c]] = c; } bool dfs(int d) { //d为递归深度 if (R[0] == 0) { //找到解 ansd = d; //记录解的长度 return true; } //找S最小的C列 int c = R[0]; //第一个未删除的列 for (int i = R[0]; i != 0; i = R[i]) if (S[i]<S[c]) c = i; remove(c); //删除第c列 for (int i = D[c]; i != c; i = D[i]) { //用结点i所在的行覆盖第c列 ans[d] = row[i]; for (int j = R[i]; j != i; j = R[j]) remove(col[j]); //删除节结点i所在行覆盖第c列 if (dfs(d+1)) return true; for (int j = L[i]; j != i; j = L[j]) restore(col[j]); // 恢复 } restore(c); //恢复 return false; } bool solve(vector<int> &v) { v.clear(); if(!dfs(0)) return false; for (int i = 0; i < ansd; i++) v.push_back(ans[i]); return true; } }; const int SLOT = 0; const int ROW = 1; const int COL = 2; const int SUB = 3; inline int encode(int a, int b, int c) { return a*256 + b*16 + c + 1; } inline void decode(int code, int &a, int &b, int &c) { code--; c = code%16; code /= 16; b = code%16; code /= 16; a = code; } char puzzle[16][20]; bool read() { for (int i = 0; i < 16; i++) if (scanf("%s", puzzle[i])!=1) return false; return true; } DLX solver; int main() { #ifdef Phantom01 freopen("LA2659.txt", "r", stdin); #endif //Phantom01 int T= 0; while (read()) { if (T!=0) puts(""); T++; solver.init(1024); for (int r = 0; r < 16; r++) for (int c = 0; c < 16; c++) for (int v = 0; v < 16; v++) if (puzzle[r][c]=='-'|| puzzle[r][c]=='A'+v) { vector<int> columns; columns.push_back(encode(SLOT, r, c)); columns.push_back(encode(ROW, r, v)); columns.push_back(encode(COL, c, v)); columns.push_back(encode(SUB, (r/4)*4+c/4, v)); solver.addRow(encode(r, c, v), columns); } vector<int> ans; if (!solver.solve(ans)) while (1) ; for (int i = 0; i < ans.size(); i++) { int r, c, v; decode(ans[i], r, c, v); puzzle[r][c] = 'A'+v; } for (int i = 0; i < 16; i++) { printf("%s\n", puzzle[i]); } } return 0; }
View Code
相关文章推荐
- 【UVALive】2659 Sudoku 【数独】精确覆盖
- UVAlive 4763 Sudoku Extension【DLX】
- LA_2659_POJ_3076_ZOJ_3122_Sudoku(DancingLinksX精确覆盖,数独题模板)
- UVALive 5220 Internet Bandwidth(最大流,模板题)
- UVALive 5908 更新一下线段相交模板
- UVALive 3887 边权极差最小生成树模板
- UVALive-4670 Dominating Patterns / 洛谷 3796 【模板】AC自动机
- Edge Case(UVALive 6270)(大数加法)(模板)
- Trie模板 UVALive 3942 Remember the Word
- UVALive 6184 - One-Dimensional Cellular Automaton 高斯消元模板题 (2012 Tokyo)
- 计算几何【套模板,推荐模板】 Separating Pebbles UVALive - 7461
- UVA 1469 Sudoku Extension【加强版数独 DLX】
- UVALive - 4513 Stammering Aliens(后缀数组模板)
- Fixed Partition Memory Management UVALive - 2238 建图很巧妙 km算法左右顶点个数不等模板以及需要注意的问题 求最小权匹配
- 文章标题 UVALive 4670 : Dominating Patterns (AC自动机模板题)
- 【字符串匹配】UVALive 4670 模板题
- uva 1309 数独【DLX】
- DLX算法及应用(一)DLX模板+解数独
- 伸展树模板(BZOJ 1500,UVALive 3961 HDU 1890)
- (模板题)UVALive 7362 Farey(欧拉函数)