舞蹈链解决数独问题,也是很经典的一个数独问题
直接套用的书上的模版
//leehaoze
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int INF = 1<<29;
#define INC_SAT( val ) (val = ((val)+1 > (val)) ? (val)+1 : (val))
#define ARR_SIZE( a ) ( sizeof( (a) ) / sizeof( (a[0]) ) )
#define ULL unsigned long long
const int maxn = 4 * 4 * 4 * 4 * 4 * 4;
const int maxnode = 4 * 4 * 4 * 4 * 4 * 4;
const int maxr = 4 * 4 * 4 * 4 * 4 * 4;
struct DLX{
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){
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[n] = 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;
}
#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){
++S[col[j]];
U[D[j]] = j;
D[U[j]] = j;
}
L[R[c]] = c;
R[L[c]] = c;
}
bool dfs(int d){
if(R[0] == 0){
ansd = d;
return true;
}
int c = R[0];
FOR(i,R,0)if(S[i] < S[c] ) c= i;
remove(c);
FOR(i,D,c){
ans[d] = row[i];
FOR(j,R,i)remove(col[j]);
if(dfs(d+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;
const int SLOT = 0;
const int ROW = 1;
const int COL = 2;
const int SUB = 3;
int encode(int a,int b,int c){
return a*16+b*4+c+1;
}
void decode(int code,int &a,int &b,int &c){
code--;
c = code%4; code /= 4;
b = code%4; code /= 4;
a = code;
}
char puzzle[5][5];
void read(){
for (int i = 0; i < 4; ++i) {
scanf("%s",puzzle[i]);
}
}
int main() {
int T,cases = 1;
scanf("%d",&T);
while(T--) {
read();
solver.init(64);
for (int r = 0; r < 4; ++r)
for (int c = 0; c < 4; ++c)
for (int v = 0; v < 4; ++v)
if (puzzle[r][c] == '*' || puzzle[r][c] == '1' + 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 / 2 * 2 + c / 2, v));
solver.addRow(encode(r, c, v), columns);
}
vector<int> ans;
solver.solve(ans);
for (int i = 0; i < ans.size(); ++i) {
int r,c,v;
decode(ans[i],r,c,v);
puzzle[r][c] = '1' + v;
}
printf("Case #%d:\n",cases++);
for (int i = 0; i < 4; ++i) {
printf("%s\n",puzzle[i]);
}
}
return 0;
}