码迷,mamicode.com
首页 > 其他好文 > 详细

UVa 1309 DLX Sudoku

时间:2015-09-18 23:13:35      阅读:167      评论:0      收藏:0      [点我收藏+]

标签:

16×16的数独。

看白书学的DLX,有些细节还有待消化,贴个模板先。

 

技术分享
  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 #include <vector>
  5 #include <queue>
  6 using namespace std;
  7 
  8 const int maxn = 16;
  9 const int maxnode = 16384 + 100;
 10 const int maxr = 4096 + 10;
 11 const int maxc = 1024 + 10;
 12 
 13 #define FOR(i,A,s) for(int i = A[s]; i != s; i = A[i])
 14 
 15 struct DLX
 16 {
 17     int n, sz;
 18     int S[maxc];
 19 
 20     int row[maxnode], col[maxnode];
 21     int L[maxnode], R[maxnode], U[maxnode], D[maxnode];
 22 
 23     int ansd, ans[maxr];
 24 
 25     void init(int n)
 26     {
 27         this-> n = n;
 28 
 29         for(int i = 0; i <= n; i++) {
 30             U[i] = D[i] = i; L[i] = i - 1; R[i] = i + 1;
 31         }
 32         L[0] = n; R[n] = 0;
 33 
 34         sz = n + 1;
 35         memset(S, 0, sizeof(S));
 36     }
 37 
 38     void AddRow(int r, vector<int> columns)
 39     {
 40         int first = sz;
 41         for(int i = 0; i < columns.size(); i++)
 42         {
 43             int c = columns[i];
 44             L[sz] = sz - 1; R[sz] = sz + 1; D[sz] = c; U[sz] = U[c];
 45             D[U[c]] = sz; U[c] = sz;
 46             row[sz] = r; col[sz] = c;
 47             S[c]++; sz++;
 48         }
 49         R[sz - 1] = first; L[first] = sz - 1;
 50     }
 51 
 52     void remove(int c)
 53     {
 54         L[R[c]] = L[c];
 55         R[L[c]] = R[c];
 56         FOR(i,D,c)
 57             FOR(j,R,i) { U[D[j]] = U[j]; D[U[j]] = D[j]; --S[col[j]]; }
 58     }
 59 
 60     void restore(int c)
 61     {
 62         FOR(i,U,c)
 63             FOR(j,L,i) { ++S[col[j]]; U[D[j]] = j; D[U[j]] = j; }
 64         L[R[c]] = c;
 65         R[L[c]] = c;
 66     }
 67 
 68     bool dfs(int d)
 69     {
 70         if(R[0] == 0) { ansd = d; return true; }
 71 
 72         int c = R[0];
 73         FOR(i,R,0) if(S[i] < S[c]) c = i;
 74 
 75         remove(c);
 76         FOR(i,D,c)
 77         {
 78             ans[d] = row[i];
 79             FOR(j,R,i) remove(col[j]);
 80             if(dfs(d + 1)) return true;
 81             FOR(j,L,i) restore(col[j]);
 82         }
 83         restore(c);
 84 
 85         return false;
 86     }
 87 
 88     bool solve(vector<int>& v)
 89     {
 90         v.clear();
 91         if(!dfs(0)) return false;
 92         for(int i = 0; i < ansd; i++) v.push_back(ans[i]);
 93         return true;
 94     }
 95 }solver;
 96 
 97 const int SLOT = 0;
 98 const int ROW = 1;
 99 const int COL = 2;
100 const int SUB = 3;
101 
102 int encode(int a, int b, int c) {
103     return a * 256 + b * 16 + c + 1;
104 }
105 
106 void decode(int code, int& a, int& b, int& c) {
107     code--;
108     c = code % 16; code /= 16;
109     b = code % 16; code /= 16;
110     a = code % 16;
111 }
112 
113 char G[maxn][maxn + 10];
114 
115 bool read()
116 {
117     for(int i = 0; i < 16; i++)
118         if(scanf("%s", G[i]) != 1) return false;
119     return true;
120 }
121 
122 int main()
123 {
124     int kase = 0;
125     while(read())
126     {
127         if(kase++ > 0) puts("");
128         
129         solver.init(1024);
130         for(int r = 0; r < 16; r++)
131             for(int c = 0; c < 16; c++)
132                 for(int v = 0; v < 16; v++)
133                     if(G[r][c] == - || G[r][c] == A + v) {
134                         vector<int> columns;
135                         //一行完成四个任务
136                         columns.push_back(encode(SLOT, r, c));
137                         columns.push_back(encode(ROW, r, v));
138                         columns.push_back(encode(COL, c, v));
139                         columns.push_back(encode(SUB, (r/4)*4+c/4, v));
140                         solver.AddRow(encode(r,c,v), columns);
141                     }
142 
143         vector<int> ans;
144         solver.solve(ans);
145 
146         for(int i = 0; i < ans.size(); i++) {
147             int r, c, v;
148             decode(ans[i], r, c, v);
149             G[r][c] = A + v;
150         }
151 
152         for(int i = 0; i < 16; i++) printf("%s\n", G[i]);
153     }
154 
155     return 0;
156 }
代码君

 

UVa 1309 DLX Sudoku

标签:

原文地址:http://www.cnblogs.com/AOQNRMGYXLMV/p/4820524.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!