数独,用舞蹈链解决。
建
4∗9∗9
列,分别表示第i行数j的位置,第i列数j的位置,第i格数j的位置,位置为(i,j)的数是否被使用。
最后一个
9∗9
是限制每个格只有一个数。
建
9∗9∗9
行,表示格(i,j)填数k的情况。
注意要加一个A*优化
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define N 250000
int T,cnt,hd;
char s[11][11];
int p[N][4],rem[330],bel[N],row[N];
void init()
{
memset(p,0,sizeof(p));
memset(rem,0,sizeof(rem));
memset(bel,0,sizeof(bel));
}
void ins(int x,int dir,int y)
{
int t=p[x][dir];
p[x][dir]=y;p[y][dir]=t;
p[t][dir^1]=y;p[y][dir^1]=x;
}
void del(int x,int dir)
{
p[p[x][dir]][dir^1]=p[x][dir^1];
p[p[x][dir^1]][dir]=p[x][dir];
}
void res(int x,int dir)
{
p[p[x][dir]][dir^1]=x;
p[p[x][dir^1]][dir]=x;
}
void del_con(int x)
{
if(!x)return;
del(x,2);
for(int i=p[x][1];i!=x;i=p[i][1])
for(int j=p[i][2];j!=i;j=p[j][2])
del(j,0),rem[bel[j]]--;
}
void res_con(int x)
{
if(!x)return;
res(x,2);
for(int i=p[x][1];i!=x;i=p[i][1])
for(int j=p[i][2];j!=i;j=p[j][2])
res(j,0),rem[bel[j]]++;
}
int dlx()
{
if(p[hd][2]==hd)
{
for(int i=1;i<=9;i++)
puts(s[i]+1);
return 1;
}
int mn=p[hd][3];
for(int i=p[hd][3];i!=hd;i=p[i][3])
if(rem[i]<rem[mn])mn=i;
del_con(mn);
for(int now=p[mn][1];now!=mn;now=p[now][1])
{
for(int i=p[now][3];i!=now;i=p[i][3])
del_con(bel[i]);
int t=row[now]-1;
s[t/81+1][t/9%9+1]=t%9+1+'0';
if(dlx())return 1;
for(int i=p[now][3];i!=now;i=p[i][3])
res_con(bel[i]);
}
res_con(mn);
return 0;
}
int main()
{
//freopen("tt.in","r",stdin);
scanf("%d",&T);
for(;T--;)
{
init();
for(int i=1;i<=9;i++)
scanf("%s",s[i]+1);
hd=0;cnt=324;
for(int i=1;i<=324;i++)
ins(hd,2,i),p[i][0]=p[i][1]=i;
for(int i=1;i<=9;i++)
for(int j=1;j<=9;j++)
for(int k=1,beg;k<=9;k++)
{
ins(hd,0,++cnt);beg=cnt;
p[cnt][2]=p[cnt][3]=cnt;
if(s[i][j]!='0'&&s[i][j]!=k+'0')continue;
int t=(i-1)*81+(j-1)*9+k;
ins(beg,2,++cnt);row[cnt]=t;
ins(bel[cnt]=(i-1)*9+k,0,cnt);rem[bel[cnt]]++;
ins(beg,2,++cnt);row[cnt]=t;
ins(bel[cnt]=(j-1)*9+k+81,0,cnt);rem[bel[cnt]]++;
ins(beg,2,++cnt);row[cnt]=t;
ins(bel[cnt]=((i-1)/3*3+(j-1)/3)*9+k+81*2,0,cnt);rem[bel[cnt]]++;
ins(beg,2,++cnt);row[cnt]=t;
ins(bel[cnt]=(i-1)*9+j+81*3,0,cnt);rem[bel[cnt]]++;
}
dlx();
}
return 0;
}