题目:
http://poj.org/problem?id=2676
题意:
数独,每行1-9,每列1-9,每3*3小格1-9,填数,不能重复
方法:Dancing Links(16ms)或者DFS暴搜(400-900ms)
Dancing Links(DLX) 是为了解决矩阵精确覆盖问题的算法,算法效率非常高
使用DLX解决的问题必须转化为矩阵精确覆盖问题:
1、DLX详解:
http://wenku.baidu.com/view/d8f13dc45fbfc77da269b126.html
2、转化方法:
非常详细的讲解:http://www.cnblogs.com/grenet/p/3163550.html
约束1:每个格子只能填一个数:dlx.Link(t, encode(0, i, j));
约束2:每行需1-9:dlx.Link(t, encode(1, i, k - 1));
约束3:每列需1-9:dlx.Link(t, encode(2, j, k - 1));
约束4:每3*3格子需1-9:dlx.Link(t, encode(3, (i / 3) * 3 + j / 3, k - 1));
1 void build()
2 {
3 for (int i = 0; i < 9; i++)
4 for (int j = 0; j < 9; j++)
5 for (int k = 1; k <= 9; k++)
6 if (mtx[i][j] == '0' || mtx[i][j] == k + '0')
7 {
8 int t = encode(i, j, k - 1);
9 dlx.Link(t, encode(0, i, j));
10 dlx.Link(t, encode(1, i, k - 1));
11 dlx.Link(t, encode(2, j, k - 1));
12 dlx.Link(t, encode(3, (i / 3) * 3 + j / 3, k - 1));
13 }
14 }
DLX模板(转自kuangbin(http://www.cnblogs.com/kuangbin/p/3752854.html)):
1 const int maxnode = 100010; 2 const int MaxM = 1010; 3 const int MaxN = 1010; 4 struct DLX 5 { 6 int n, m, size; 7 int U[maxnode], D[maxnode], R[maxnode], L[maxnode], Row[maxnode], Col[maxnode]; 8 int H[MaxN], S[MaxM]; 9 int ansd, ans[MaxN]; 10 void init(int _n, int _m) 11 { 12 n = _n; 13 m = _m; 14 for (int i = 0; i <= m; i++) 15 { 16 S[i] = 0; 17 U[i] = D[i] = i; 18 L[i] = i - 1; 19 R[i] = i + 1; 20 } 21 R[m] = 0; L[0] = m; 22 size = m; 23 for (int i = 1; i <= n; i++) 24 H[i] = -1; 25 } 26 void Link(int r, int c) 27 { 28 ++S[Col[++size] = c]; 29 Row[size] = r; 30 D[size] = D[c]; 31 U[D[c]] = size; 32 U[size] = c; 33 D[c] = size; 34 if (H[r] < 0)H[r] = L[size] = R[size] = size; 35 else 36 { 37 R[size] = R[H[r]]; 38 L[R[H[r]]] = size; 39 L[size] = H[r]; 40 R[H[r]] = size; 41 } 42 } 43 void remove(int c) 44 { 45 L[R[c]] = L[c]; R[L[c]] = R[c]; 46 for (int i = D[c]; i != c; i = D[i]) 47 for (int j = R[i]; j != i; j = R[j]) 48 { 49 U[D[j]] = U[j]; 50 D[U[j]] = D[j]; 51 --S[Col[j]]; 52 } 53 } 54 void resume(int c) 55 { 56 for (int i = U[c]; i != c; i = U[i]) 57 for (int j = L[i]; j != i; j = L[j]) 58 ++S[Col[U[D[j]] = D[U[j]] = j]]; 59 L[R[c]] = R[L[c]] = c; 60 } 61 //d为递归深度 62 bool Dance(int d) 63 { 64 if (R[0] == 0) 65 { 66 ansd = d; 67 return true; 68 } 69 int c = R[0]; 70 for (int i = R[0]; i != 0; i = R[i]) 71 if (S[i] < S[c]) 72 c = i; 73 remove(c); 74 for (int i = D[c]; i != c; i = D[i]) 75 { 76 ans[d] = Row[i]; 77 for (int j = R[i]; j != i; j = R[j])remove(Col[j]); 78 if (Dance(d + 1))return true; 79 for (int j = L[i]; j != i; j = L[j])resume(Col[j]); 80 } 81 resume(c); 82 return false; 83 } 84 };
代码:
1 /******************************************** 2 *ACM Solutions 3 * 4 *@Title: 5 *@Version: 1.0 6 *@Time: 2014-xx-xx 7 *@Solution: http://www.cnblogs.com/xysmlx/p/xxxxxxx.html 8 * 9 *@Author: xysmlx(Lingxiao Ma) 10 *@Blog: http://www.cnblogs.com/xysmlx 11 *@EMail: xysmlx@163.com 12 * 13 *Copyright (C) 2011-2015 xysmlx(Lingxiao Ma) 14 ********************************************/ 15 // #pragma comment(linker, "/STACK:102400000,102400000") 16 #include <cstdio> 17 #include <iostream> 18 #include <cstring> 19 #include <string> 20 #include <cmath> 21 #include <set> 22 #include <list> 23 #include <map> 24 #include <iterator> 25 #include <cstdlib> 26 #include <vector> 27 #include <queue> 28 #include <stack> 29 #include <algorithm> 30 #include <functional> 31 using namespace std; 32 typedef long long LL; 33 #define pb push_back 34 #define ROUND(x) round(x) 35 #define FLOOR(x) floor(x) 36 #define CEIL(x) ceil(x) 37 const int maxn = 0; 38 const int maxm = 0; 39 const int inf = 0x3f3f3f3f; 40 const LL inf64 = 0x3f3f3f3f3f3f3f3fLL; 41 const double INF = 1e30; 42 const double eps = 1e-6; 43 const int P[4] = {0, 0, -1, 1}; 44 const int Q[4] = {1, -1, 0, 0}; 45 const int PP[8] = { -1, -1, -1, 0, 0, 1, 1, 1}; 46 const int QQ[8] = { -1, 0, 1, -1, 1, -1, 0, 1}; 47 48 const int maxnode = 100010; 49 const int MaxM = 1010; 50 const int MaxN = 1010; 51 struct DLX 52 { 53 int n, m, size; 54 int U[maxnode], D[maxnode], R[maxnode], L[maxnode], Row[maxnode], Col[maxnode]; 55 int H[MaxN], S[MaxM]; 56 int ansd, ans[MaxN]; 57 void init(int _n, int _m) 58 { 59 n = _n; 60 m = _m; 61 for (int i = 0; i <= m; i++) 62 { 63 S[i] = 0; 64 U[i] = D[i] = i; 65 L[i] = i - 1; 66 R[i] = i + 1; 67 } 68 R[m] = 0; L[0] = m; 69 size = m; 70 memset(H, -1, sizeof(H)); 71 // for (int i = 1; i <= n; i++) 72 // H[i] = -1; 73 } 74 void Link(int r, int c) 75 { 76 ++S[Col[++size] = c]; 77 Row[size] = r; 78 D[size] = D[c]; 79 U[D[c]] = size; 80 U[size] = c; 81 D[c] = size; 82 if (H[r] < 0)H[r] = L[size] = R[size] = size; 83 else 84 { 85 R[size] = R[H[r]]; 86 L[R[H[r]]] = size; 87 L[size] = H[r]; 88 R[H[r]] = size; 89 } 90 } 91 void remove(int c) 92 { 93 L[R[c]] = L[c]; R[L[c]] = R[c]; 94 for (int i = D[c]; i != c; i = D[i]) 95 for (int j = R[i]; j != i; j = R[j]) 96 { 97 U[D[j]] = U[j]; 98 D[U[j]] = D[j]; 99 --S[Col[j]]; 100 } 101 } 102 void resume(int c) 103 { 104 for (int i = U[c]; i != c; i = U[i]) 105 for (int j = L[i]; j != i; j = L[j]) 106 ++S[Col[U[D[j]] = D[U[j]] = j]]; 107 L[R[c]] = R[L[c]] = c; 108 } 109 //d为递归深度 110 bool Dance(int d) 111 { 112 if (R[0] == 0) 113 { 114 ansd = d; 115 return true; 116 } 117 int c = R[0]; 118 for (int i = R[0]; i != 0; i = R[i]) 119 if (S[i] < S[c]) 120 c = i; 121 remove(c); 122 for (int i = D[c]; i != c; i = D[i]) 123 { 124 ans[d] = Row[i]; 125 for (int j = R[i]; j != i; j = R[j])remove(Col[j]); 126 if (Dance(d + 1))return true; 127 for (int j = L[i]; j != i; j = L[j])resume(Col[j]); 128 } 129 resume(c); 130 return false; 131 } 132 } dlx; 133 134 int kase; 135 int n, m; 136 char mtx[20][20]; 137 void init() 138 { 139 n = 9, m = 9; 140 kase++; 141 dlx.init(1, 324); 142 } 143 void input() 144 { 145 for (int i = 0; i < 9; i++) 146 scanf("%s", mtx[i]); 147 } 148 void debug() 149 { 150 // 151 } 152 int encode(int a, int b, int c) 153 { 154 return a * 81 + b * 9 + c + 1; 155 } 156 void decode(int code, int &a, int &b, int &c) 157 { 158 code--; 159 c = code % 9; 160 code /= 9; 161 b = code % 9; 162 code /= 9; 163 a = code; 164 } 165 void build() 166 { 167 for (int i = 0; i < 9; i++) 168 for (int j = 0; j < 9; j++) 169 for (int k = 1; k <= 9; k++) 170 if (mtx[i][j] == '0' || mtx[i][j] == k + '0') 171 { 172 int t = encode(i, j, k - 1); 173 dlx.Link(t, encode(0, i, j)); 174 dlx.Link(t, encode(1, i, k - 1)); 175 dlx.Link(t, encode(2, j, k - 1)); 176 dlx.Link(t, encode(3, (i / 3) * 3 + j / 3, k - 1)); 177 } 178 } 179 void solve() 180 { 181 build(); 182 dlx.Dance(0); 183 for (int i = 0; i < dlx.ansd; i++) 184 { 185 int r, c, k; 186 decode(dlx.ans[i], r, c, k); 187 mtx[r][c] = k + '1'; 188 } 189 } 190 void output() 191 { 192 for (int i = 0; i < 9; i++) 193 printf("%s ", mtx[i]); 194 } 195 int main() 196 { 197 // int size = 256 << 20; // 256MB 198 // char *p = (char *)malloc(size) + size; 199 // __asm__("movl %0, %%esp " :: "r"(p)); 200 201 // std::ios_base::sync_with_stdio(false); 202 #ifdef xysmlx 203 freopen("in.cpp", "r", stdin); 204 #endif 205 206 kase = 0; 207 int T; 208 scanf("%d", &T); 209 while (T--) 210 { 211 init(); 212 input(); 213 solve(); 214 output(); 215 } 216 return 0; 217 }