数独为M × M,则有M × M × M行 、M × M × 4列
下面是数独题任意大小模板:
#include<bits/stdc++.h>
using namespace std;
const int M=16; // 数独大小
const int MN=M*M*M+10;
const int MM=M*M*4+10;
const int MNN=MN*4+MM; // 最大点数,数独问题节点没有那么多
struct DLX {
int n,m,si; // n行数m列数si目前有的节点数
int U[MNN],D[MNN],L[MNN],R[MNN],Row[MNN],Col[MNN];
int H[MN],S[MM]; // 记录行的选择情况和列的覆盖情况
int ansd,ans[MN];
void init(int _n,int _m) { // 初始化空表
n=_n;m=_m;
for(int i=0; i<=m; i++) { // 初始化第一横行(表头)
S[i]=0;U[i]=D[i]=i;L[i]=i-1;R[i]=i+1;
}
R[m]=0;L[0]=m;si=m;
for(int i=1; i<=n; i++) H[i]=-1;
}
void link(int r,int c) {
++S[Col[++si]=c];Row[si]=r;
D[si]=D[c];U[D[c]]=si;U[si]=c;D[c]=si;
if(H[r]<0) H[r]=L[si]=R[si]=si;
else {
R[si]=R[H[r]];L[R[H[r]]]=si;
L[si]=H[r];R[H[r]]=si;
}
}
void remove(int c) { //列 表中删掉c列
L[R[c]]=L[c];R[L[c]]=R[c];
for(int i=D[c]; i!=c; i=D[i])
for(int j=R[i]; j!= i; j=R[j])
U[D[j]]=U[j],D[U[j]]=D[j],--S[Col[j]];
}
void resume(int c) { // 恢复c列
for(int i=U[c]; i!=c; i=U[i])
for(int j=L[i]; j!=i; j=L[j])
++S[Col[U[D[j]]=D[U[j]]=j]];
L[R[c]]=R[L[c]]=c;
}
bool dance(int d) {
if(R[0]==0) { ansd=d;return 1; }
int c=R[0];
for(int i=R[0]; i!=0; i=R[i])if(S[i]<S[c])c=i;
remove(c);
for(int i=D[c]; i!=c; i=D[i]) {
ans[d]=Row[i];
for(int j=R[i]; j!= i; j=R[j]) remove(Col[j]);
if(dance(d+1)) return 1;
for(int j=L[i]; j!=i; j=L[j]) resume(Col[j]);
}
resume(c); return 0;
}
void place(int &r,int &c1,int &c2,int &c3,int &c4,int i,int j,int k) {
r=(i*M+j)*M+k;
c1=M*M*0+i*M+j+1;
c2=M*M*1+i*M+k;
c3=M*M*3+j*M+k;
c4=M*M*2+((i/4)*4+(j/4))*M+k;//确定第几个小九宫(16宫?),九宫4改3
}
} dlx;
char ss[M+5][M+5];
int main() {
int ca=0;
while(scanf("%s",ss[0])!=EOF) {
for(int i=1; i<M; i++)
scanf("%s",ss[i]);
dlx.init(M*M*M,M*M*4);
int r,c1,c2,c3,c4;
for(int i = 0; i < M; i++)
for(int j = 0; j < M; j++)
for(int k = 1; k <= M; k++)
if(ss[i][j] == '-' || ss[i][j] == 'A'+k-1) {
dlx.place(r,c1,c2,c3,c4,i,j,k);
dlx.link(r,c1);
dlx.link(r,c2);
dlx.link(r,c3);
dlx.link(r,c4);
}
dlx.dance(0);
int v,x,y;
for(int i=0; i<dlx.ansd; i++) {
v=(dlx.ans[i]-1)%M;
x=(dlx.ans[i]-1)/M/M;
y=(dlx.ans[i]-1)/M%M;
ss[x][y]=v+'A';
}
if(ca++) printf("\n");
for(int i=0; i<M; i++) printf("%s\n",ss[i]);
}
}