题意:给定了一个没有填完的数独,然后输出最后的解
解法:暴力dfs可搞 但是不能枉费经典的跳舞链模型
一共是81*9行代表了每一个格子填的数 一共81*4列分别代表了4中约束条件
1 每一行必须有数字
2 每一行的数字必须是1-9
3 每一列的数字必须是1-9
4 每一个九宫格的数字必须是1-9
然后建跳舞链直接跑即可
#include<cstdio>
#include<iostream>
using namespace std;
#define maxr (9*9*9+11)
#define maxc (9*9*4+11)
int l[maxc+(maxr<<2)],r[maxc+(maxr<<2)],U[maxc+(maxr<<2)],D[maxc+(maxr<<2)];
int tot[maxc],nRow[maxc+maxr*5],nCol[maxc+maxr*5];
int head[10][10][10],cnt,mp[10][10];
bool scan(){
char ch[90];
for (int i=1;i<=9;i++)
for (int j=1;j<=9;j++){
if(!~scanf("%s",ch))return 0;
if(*ch=='?')mp[i][j]=0;
else mp[i][j]=*ch-'0';
}
return 1;
}
int sub(int i,int j){
--i;--j;
return (i/3)*3+(j/3+1);
}
void ins(int c,int cnt){
U[D[c]]=cnt;
D[cnt]=D[c];
U[cnt]=c;
D[c]=cnt;
tot[c]++;
nCol[cnt]=c;
}
void kill(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];
tot[nCol[j]]--;
}
}
void reborn(int c){
for(int i=U[c];i!=c;i=U[i])
for(int j=l[i];j!=i;j=l[j]){
U[D[j]]=D[U[j]]=j;
tot[nCol[j]]++;
}
l[r[c]]=r[l[c]]=c;
}
int dfs(int k){
if(k>81)return 1;
int c=0,mi=INT_MAX;
for(int i=r[0];i!=0;i=r[i]){
if(!tot[i])return 0;
if(tot[i]<mi){
mi=tot[i];
c=i;
}
}
kill(c);
for(int i=D[c];i!=c;i=D[i]){
int tmp=nRow[i];
mp[tmp/100][(tmp/10)%10]=tmp%10;
for(int j=r[i];j!=i;j=r[j])
kill(nCol[j]);
if(dfs(k+1))return 1;
for(int j=l[i];j!=i;j=l[j])
reborn(nCol[j]);
}
reborn(c);
return 0;
}
int main()
{
int cas=1;
while(1){
if(!scan())break;
if(cas!=1)printf("\n");
cas++;
//init
for(int i=0;i<=(81<<2);++i){
tot[i]=0;l[i]=i-1;r[i]=i+1;
U[i]=D[i]=i;
nCol[i]=0;
}l[0]=81*4;r[81*4]=0;
cnt=81*4;
for(int i=1;i<=9;i++)
for(int j=1;j<=9;j++){
if(mp[i][j]){
int k=mp[i][j];
for (int u=1;u<=4;u++){
l[cnt+u]=cnt+u-1;
r[cnt+u]=cnt+u+1;
nRow[cnt+u]=100*i+10*j+k;
}
l[cnt+1]=cnt+4; r[cnt+4]=cnt+1;
head[i][j][k]=cnt+1;
ins((i-1)*9+j,cnt+1);
ins(81+(i-1)*9+k,cnt+2);
ins(81*2+(j-1)*9+k,cnt+3);
ins(81*3+(sub(i,j)-1)*9+k,cnt+4);
cnt+=4;
}
else for(int k=1;k<=9;k++){
for(int u=1;u<=4;u++){
l[cnt+u]=cnt+u-1;
r[cnt+u]=cnt+u+1;
nRow[cnt+u]=100*i+10*j+k;
}
l[cnt+1]=cnt+4; r[cnt+4]=cnt+1;
head[i][j][k]=cnt+1;
ins((i-1)*9+j,cnt+1);
ins(81+(i-1)*9+k,cnt+2);
ins(81*2+(j-1)*9+k,cnt+3);
ins(81*3+(sub(i,j)-1)*9+k,cnt+4);
cnt+=4;
}
}
int k=0;
for(int i=1;i<=9;i++)
for(int j=1;j<=9;j++)
if(mp[i][j]){
k++;
kill(nCol[head[i][j][mp[i][j]]]);
for(int u=r[head[i][j][mp[i][j]]];u!=head[i][j][mp[i][j]];u=r[u])
kill(nCol[u]);
}
dfs(k+1);
for(int i=1;i<=9;++i,printf("\n"))
for(int j=1;j<=9;++j)
printf(j==1?"%d":" %d",mp[i][j]);
}
return 0;
}