思路:裸的DLX解数独。关键是建图,感觉还不如写个dfs直接,DLX写这个的代码很烦。
#include<set> #include<map> #include<cmath> #include<queue> #include<cstdio> #include<vector> #include<string> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #define pb push_back #define mp make_pair #define Maxn 400010 #define Maxm 200010 #define LL __int64 #define Abs(x) ((x)>0?(x):(-x)) #define lson(x) (x<<1) #define rson(x) (x<<1|1) #define inf 100000 #define lowbit(x) (x&(-x)) #define clr(x,y) memset(x,y,sizeof(x)) #define Mod 1000000007 using namespace std; int L[Maxn],R[Maxn],D[Maxn],U[Maxn],S[Maxn],C[Maxn],X[Maxn],Q[Maxn],H[1010],id; int g[10][10]; void init(int m) { int i; for(i=0;i<=m;i++){ D[i]=U[i]=i; L[i+1]=i; R[i]=i+1; S[i]=0; } R[m]=0; id=m+1; clr(H,-1); } void ins(int r,int c) { D[id]=D[c]; U[id]=c; U[D[c]]=id; D[c]=id; S[c]++; if(H[r]<0) H[r]=L[id]=R[id]=id; else{ L[id]=H[r]; R[id]=R[H[r]]; L[R[H[r]]]=id; R[H[r]]=id; } C[id]=c; X[id++]=r; } void Remove(int c) { int i,j; R[L[c]]=R[c]; L[R[c]]=L[c]; for(i=D[c];i!=c;i=D[i]){ for(j=R[i];j!=i;j=R[j]){ D[U[j]]=D[j]; U[D[j]]=U[j]; S[C[j]]--; } } } void Resume(int c) { int i,j; R[L[c]]=c; L[R[c]]=c; for(i=D[c];i!=c;i=D[i]){ for(j=R[i];j!=i;j=R[j]){ U[D[j]]=j; D[U[j]]=j; S[C[j]]++; } } } bool dfs(int k) { int i,j,c,temp; if(R[0]==0){ for(i=0;i<k;i++){ int r,k; temp=X[Q[i]]; k=temp%9; if(!k) k=9; c=(temp%81)/9; if(temp%81==0) c=9; if(temp%81%9) c++; r=temp/81; if(temp%81) r++; g[r][c]=k; } return true; } temp=inf; for(i=R[0];i;i=R[i]){ if(S[i]<temp){ temp=S[i]; c=i; } } Remove(c); for(i=D[c];i!=c;i=D[i]){ Q[k]=i; for(j=R[i];j!=i;j=R[j]) Remove(C[j]); if(dfs(k+1)) return true; for(j=L[i];j!=i;j=L[j]) Resume(C[j]); } Resume(c); return false; } void build() { int i,j,k,b,r,c; init(324); for(i=1;i<=9;i++){ for(j=1;j<=9;j++){ if(g[i][j]){ r=(i-1)*81+(j-1)*9+g[i][j]; c=(i-1)*9+g[i][j]; ins(r,c); c=81+(j-1)*9+g[i][j]; ins(r,c); c=162+(i-1)*9+j; ins(r,c); c=81*3+(((i-1)/3)*3+(j+2)/3-1)*9+g[i][j]; ins(r,c); continue; } for(k=1;k<=9;k++){ r=(i-1)*81+(j-1)*9+k; c=(i-1)*9+k; ins(r,c); c=81+(j-1)*9+k; ins(r,c); c=162+(i-1)*9+j; ins(r,c); c=81*3+(((i-1)/3)*3+(j+2)/3-1)*9+k; ins(r,c); } } } } int main() { int t,i,j,f=0; char str[20]; scanf("%d",&t); while(t--){ clr(g,0); for(i=1;i<=9;i++){ scanf("%s",str); for(j=0;j<9;j++){ if(str[j]!='?') g[i][j+1]=str[j]-'0'; } } if(t) scanf("%s",str); build(); if(f) printf("--- "); f=1; if(!dfs(0)){ printf("impossible "); continue; } for(i=1;i<=9;i++){ for(j=1;j<=9;j++){ printf("%d",g[i][j]); } printf(" "); } } return 0; }