POJ 3076 Sudoku (DLX)
来源:互联网 发布:知乎 高帮帆布鞋搭配 编辑:程序博客网 时间:2024/05/05 19:17
16*16 的数独,DLX的最爱。想了一会儿空着的列要不要删掉,突然发现其实随它搜就好了,只影响深度不影响宽度。或者手动删除一下也没有大碍。
/* Created Time: Thursday, November 21, 2013 PM08:36:56 CST */#include <cstdio>#include <cstring>#include <algorithm>#include <vector>using namespace std;const int N = 20;const int MAXC = 4*256+7, MAXNODE = 4*256*16*16+7, MAXR = 16*16+7;struct DLX { int S[MAXC]; // 列节点数 int n,sz; // 列数,节点数 int L[MAXNODE],R[MAXNODE],U[MAXNODE],D[MAXNODE]; // 十字链表 int ans[MAXR],ansd; // 解 int row[MAXNODE],col[MAXNODE]; // 对应的行列号 void init(int num) { n = num; for (int i = 0; i <= n; i ++) { U[i] = i; D[i] = i; L[i] = i-1; R[i] = i+1; } L[0] = n; R[n] = 0; sz = n+1; memset(S,0,sizeof(S)); } void add_raw(int r,vector <int> line) { int first = sz; for (int i = 0; i < line.size(); i ++) { int c = line[i]; L[sz] = sz-1; R[sz] = sz+1; U[sz] = U[c]; D[sz] = 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; }#define FOR(i,A,s) for (int i = A[s]; i != s; i = A[i]) void remove(int c) { L[R[c]] = L[c]; R[L[c]] = R[c]; FOR(i,D,c) FOR(j,R,i) { U[D[j]] = U[j]; D[U[j]] = D[j]; S[col[j]] --; } } void restore(int c) { FOR(i,U,c) FOR(j,L,i) { U[D[j]] = j; D[U[j]] = j; S[col[j]] ++; } L[R[c]] = c; R[L[c]] = c; } bool dfs(int dep) { if (R[0]==0) { ansd = dep; return true; } int c = R[0]; FOR(i,R,0) if (S[i]<S[c]) c = i; remove(c); FOR(i,D,c) { ans[dep] = row[i]; FOR(j,R,i) remove(col[j]); if (dfs(dep+1)) return true; FOR(j,L,i) 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; }};/*******************************************************************/DLX solver;char mat[N][N];int encode(int a,int b,int c) { return (a*16+b)*16+c+1; }void decode(int v,int &a,int &b,int &c) { v --; c = v%16; v /= 16; b = v%16; v /= 16; a = v;}int get_b(int x,int y) { return x/4*4+y/4; }const int POS = 0,ROW = 1,COL = 2,BLO = 3;void get(int x,int y) { int b = get_b(x,y); for (int i = 0; i < 16; i ++) { if (mat[x][y]!='-' && mat[x][y]!=i+'A') continue; vector <int> v; v.push_back(encode(POS,x,y)); v.push_back(encode(ROW,x,i)); v.push_back(encode(COL,y,i)); v.push_back(encode(BLO,b,i)); solver.add_raw(encode(x,y,i),v); }}void work() { solver.init(4*256); for (int i = 0; i < 16; i ++) for (int j = 0; j < 16; j ++) get(i,j); vector <int> v; solver.solve(v); for (int i = 0; i < v.size(); i ++) { int a,b,c; decode(v[i],a,b,c); mat[a][b] = c+'A'; } for (int i = 0; i < 16; i ++) puts(mat[i]);}int main() { bool first = true; while (~scanf("%s",mat[0])) { for (int i = 1; i < 16; i ++) scanf("%s",mat[i]); if (first) first = false; else puts(""); work(); } return 0;}
- POJ 3076 Sudoku (DLX)
- POJ 3076 sudoku DLX
- POJ 3076 Sudoku DLX精确覆盖
- poj 3076 Sudoku dlx解数独
- POJ 3076 Sudoku (DLX解数独)
- POJ 3076 Sudoku 精确覆盖问题DLX
- POJ 3074 Sudoku DLX
- POJ 3067 Sudoku DLX
- poj 2676 Sudoku DLX
- POJ 3074 Sudoku(数据结构,DLX)
- POJ 3074 Sudoku [DLX] [SDLX]
- poj 3074 Sudoku (精确覆盖,DLX,搜索)
- DLX(精确覆盖) POJ 3074 Sudoku
- POJ 3074 Sudoku DLX精确覆盖
- poj 3074 Sudoku dlx解数独
- POJ 2676 Sudoku (DLX解数独)
- POJ 3074 Sudoku(DLX+精确覆盖)
- (模板题)poj 3074 Sudoku(DLX算法)
- 计算n的阶乘的俩种方法
- oracle sql 语句中where条件中 1=1 是什么意思
- 使环境变量即时生效
- 编程,
- 反汇编学习(3) -- add函数反汇编
- POJ 3076 Sudoku (DLX)
- URAL 1022 Genealogical Tree
- Matlab: 矩阵向量操作(1)
- win8 ubuntu
- 从今天起好好学C 语法。
- UVA 101 The Blocks Problem
- Eclipse中代码不能连接怎么办?
- acm--字符串排序
- vm-install vmware tools安装