题目
行(所有情况)81个格子 * 9个数字=9^3
列(限制条件)
1.每个格子放一个数-81
2.行限制-9行 * 9个数字
3.列限制-9列 * 9个数字
4.小宫格限制-9个小宫格 * 9个数字
把限制条件插入,dancing…
剪枝:先选择数字多的列
#include<stdio.h>
#include<string.h>
using namespace std;
const int N=9;
const int NR=N*N*N+7;
const int NC=N*N*4+7;
const int M=NR*4+NC+7;
char g[NR];
struct Node{
int u,d,l,r;
int row,col;
Node(){}
Node(int u,int d,int l,int r):u(u),d(d),l(l),r(r){}
void sign(int _r,int _c){row=_r,col=_c;}
};
struct DLX{
int n,m,sz;
Node node[M];
int head[NR],sc[NC];
int ans[NR];
void init(int _n,int _m){
n=_n,sz=m=_m;
for(int i=0;i<=m;++i)node[i]=Node(i,i,i-1,i+1),sc[i]=0;
node[m].r=0,node[0].l=m;
for(int i=0;i<=n;++i)head[i]=-1;
}
void link(int r,int c){
++sz;
node[sz].sign(r,c);
++sc[c];
node[sz].d=node[c].d;
node[node[c].d].u=sz;
node[sz].u=c;
node[c].d=sz;
if(head[r]==-1)head[r]=node[sz].l=node[sz].r=sz;
else{
node[sz].r=node[head[r]].r;
node[node[head[r]].r].l=sz;
node[sz].l=head[r];
node[head[r]].r=sz;
}
}
void remove(int c){
node[node[c].r].l=node[c].l;
node[node[c].l].r=node[c].r;
for(int i=node[c].d;i^c;i=node[i].d)
for(int j=node[i].r;j^i;j=node[j].r){
node[node[j].d].u=node[j].u;
node[node[j].u].d=node[j].d;
--sc[node[j].col];
}
}
void resume(int c){
for(int i=node[c].u;i^c;i=node[i].u)
for(int j=node[i].l;j^i;j=node[j].l){
node[node[j].d].u=node[node[j].u].d=j;
++sc[node[j].col];
}
node[node[c].r].l=node[node[c].l].r=c;
}
bool dance(int d){
int c=node[0].r;
if(!c){
for(int i=0;i<d;++i)g[(ans[i]-1)/9]=(ans[i]-1)%9+'1';
for(int i=0;i<N*N;++i)putchar(g[i]);
puts("");
return true;
}
for(int i=c;i^0;i=node[i].r)if(sc[i]<sc[c])c=i;
remove(c);
for(int i=node[c].d;i^c;i=node[i].d){
ans[d]=node[i].row;
for(int j=node[i].r;j^i;j=node[j].r)remove(node[j].col);
if(dance(d+1))return true;
for(int j=node[i].l;j^i;j=node[j].l)resume(node[j].col);
}
resume(c);
return false;
}
}sd;
int main(){
while(gets(g)!=NULL){
if(g[0]=='e')break;
sd.init(N*N*N,N*N*4);
for(int i=0;i<N;++i)for(int j=0;j<N;++j)
for(int k=1;k<=N;++k)if(g[i*N+j]=='.'||g[i*N+j]=='0'+k){
int r=(i*N+j)*N+k;
sd.link(r,i*N+j+1);
sd.link(r,N*N+i*N+k);
sd.link(r,N*N*2+j*N+k);
sd.link(r,N*N*3+((i/3)*3+j/3)*N+k);
}
sd.dance(0);
}
return 0;
}