POJ 2676 Sudoku (搜索,Dancing Links)

题目:

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 };
DLX模板(from kuangbin)

 

代码:

  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\n", 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\n" :: "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 }
POJ 2676

 

posted @ 2014-09-02 13:23  xysmlx  阅读(190)  评论(0编辑  收藏  举报