对于数独问题
1 const int N=16; //3*3数独 2 const int MaxN=N*N*N+10; // 一格能填9个数 9*9格 3 const int MaxM=N*N*4+10; // 9*9*4=(9+9+9)*9+9*9 (9+9+9)是9行 9列 9格 *9是9个数 9*9是81个格子 4 const int maxnode=MaxN*4+MaxM+10; 5 char g[MaxN]; 6 struct DLX 7 { 8 int n, m, size; 9 int U[maxnode], D[maxnode], R[maxnode], L[maxnode], Row[maxnode], Col[maxnode]; 10 int H[MaxN], S[MaxM]; // S: 各列节点数 11 int ansd, ans[MaxN]; 12 void init(int _n, int _m) 13 { 14 n=_n; 15 m=_m; 16 for(int i=0; i<=m; i++) 17 { 18 S[i]=0; //每一列元素个数 19 U[i]=D[i]=i;//上下指针 20 L[i]=i-1; //← 21 R[i]=i+1; //→ 22 } 23 R[m]=0; //循环 最后一个指向第一个 24 L[0]=m; //第一个往前指向最后一个 25 size=m; // 节点总数 26 for(int i=1; i<=n; i++) 27 H[i]=-1; //头指针 28 } 29 void Link(int r, int c) 30 { 31 S[Col[++size]=c]++; 32 Row[size]=r; 33 D[size]=D[c]; 34 U[D[c]]=size; 35 U[size]=c; 36 D[c]=size; 37 if(H[r]<0) 38 H[r]=L[size]=R[size]=size; 39 else 40 { 41 R[size]=R[H[r]]; 42 L[R[H[r]]]=size; 43 L[size]=H[r]; 44 R[H[r]]=size; 45 } 46 } 47 void remove(int c) 48 { 49 L[R[c]]=L[c]; 50 R[L[c]]=R[c]; 51 for(int i=D[c]; i!=c; i=D[i]) 52 for(int j=R[i]; j!=i; j=R[j]) 53 { 54 U[D[j]]=U[j]; 55 D[U[j]]=D[j]; 56 S[Col[j]]--; 57 } 58 } 59 void resume(int c) 60 { 61 for(int i=U[c]; i!=c; i=U[i]) 62 for(int j=L[i]; j!=i; j=L[j]) 63 S[Col[U[D[j]]=D[U[j]]=j]]++; 64 L[R[c]]=R[L[c]]=c; 65 } 66 bool Dance(int d) 67 { 68 if(R[0]==0) 69 { 70 for(int i=0;i<d;i++) 71 g[(ans[i]-1)/N]=(ans[i]-1)%N+'A'; 72 for(int i=0;i<N;i++) 73 { 74 for(int j=0;j<N;j++) 75 printf("%c", g[i*N+j]); 76 printf("\n"); 77 } 78 printf("\n"); 79 return true; 80 } 81 int c=R[0]; 82 for(int i=R[0]; i!=0; i=R[i]) 83 if(S[i]<S[c]) 84 c=i; 85 remove(c); 86 for(int i=D[c]; i!=c; i=D[i]) 87 { 88 ans[d]=Row[i]; 89 for(int j=R[i]; j!=i; j=R[j]) 90 remove(Col[j]); 91 if(Dance(d+1)) 92 return true; 93 for(int j=L[i]; j!=i; j=L[j]) 94 resume(Col[j]); 95 } 96 resume(c); 97 return false; 98 } 99 } dlx; 100 101 void palce(int &r, int &c1, int &c2, int &c3, int &c4, int i, int j, int k) 102 { 103 r=(i*N+j)*N+k; // 第几行 104 c1=i*N+j+1; // 第几个格子 105 c2=N*N+i*N+k; // 第i行上的k 106 c3=N*N*2+j*N+k; // 第j列上的k 107 c4=N*N*3+((i/4)*4+(j/4))*N+k; // 某宫中的k; 108 } 109 char s[20]; 110 int main() 111 { 112 while(~scanf("%s", g)) 113 { 114 for(int i=1;i<16;i++) 115 { 116 scanf("%s", s); 117 memcpy(g+16*i, s, 16); 118 } 119 dlx.init(N*N*N, 4*N*N); 120 for(int i=0; i<N; i++) 121 for(int j=0; j<N; j++) 122 for(int k=1; k<=16; k++) 123 if(g[i*N+j]=='-' || g[i*N+j]==k+'A'-1) 124 { 125 int r, c1, c2, c3, c4; 126 palce(r, c1, c2, c3, c4, i, j, k); 127 dlx.Link(r, c1); 128 dlx.Link(r, c2); 129 dlx.Link(r, c3); 130 dlx.Link(r, c4); 131 } 132 dlx.Dance(0); 133 } 134 return 0; 135 }