题意:
基本数独
分析:
将数独转化为精确覆盖
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
const int N=9; //n*n数独
const int maxn=N*N*N+10;
const int maxm=N*N*4+10;
const int maxnode=maxn*maxm;
char g[maxm];
struct DLX{
int n,m,size;
int U[maxnode],D[maxnode],R[maxnode],L[maxnode],Row[maxnode],Col[maxnode];
int H[maxn],S[maxm];
int ansd,ans[maxn];
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;
size=m;
for(int i=1;i<=n;i++){
H[i]=-1;
}
}
void Link(int r,int c){
++S[Col[++size]=c];
Row[size]=r;
D[size]=D[c];
U[D[c]]=size;
U[size]=c;
D[c]=size;
if(H[r]<0) H[r]=L[size]=R[size]=size;
else{
R[size]=R[H[r]];
L[R[H[r]]]=size;
L[size]=H[r];
R[H[r]]=size;
}
}
void remove(int 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){
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;
}
void dance(int d){
if(R[0]==0){
for(int i=0;i<d;i++){
g[(ans[i]-1)/9+1]=(ans[i]-1)%9+'1';
}
for(int i=1;i<=N*N;i++) printf("%c",g[i]);
printf("\n");
return ;
}
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]);
dance(d+1);
for(int j=L[i];j!=i;j=L[j]) resume(Col[j]);
}
resume(c);
}
}dlx;
inline void place(int &r,int &c1,int &c2,int &c3,int &c4,int i,int j,int k){
r=((i-1)*N+j-1)*N+k;
c1=(i-1)*N+j;
c2=(i-1)*N+k+N*N;
c3=(j-1)*N+k+N*N*2;
c4=((i-1)/(int)sqrt(N)*(int)sqrt(N)+(j-1)/(int)sqrt(N))*N+k+N*N*3;
}
int main(){
while(scanf("%s",g+1)!=EOF){
if(strcmp(g+1,"end")==0) break;
dlx.init(N*N*N,N*N*4);
int r,c1,c2,c3,c4;
for(int i=1;i<=N;i++){
for(int j=1;j<=N;j++){
for(int k=1;k<=N;k++){
if(g[(i-1)*N+j]=='.'||g[(i-1)*N+j]=='0'+k){
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);
}
return 0;
}