SuDoKu_DLX_9*9
比DFS快了4倍只用10MS就能得出结果。。
1 #include <cstdio> 2 #include <cstring> 3 #include <ctime> 4 const int XSIZE = 3; 5 const int SIZE = XSIZE * XSIZE; 6 const int MAX_C = SIZE * SIZE * 4; //最大列 7 const int MAX_R = SIZE * SIZE * SIZE; //最大行 8 const int MAX_SUDOKU = SIZE * SIZE; //数独矩阵大小 9 const int MAX_LINK = MAX_C * MAX_R; //链表最大范围 10 11 int L[MAX_LINK],R[MAX_LINK],U[MAX_LINK],D[MAX_LINK]; //抽象链表 12 int C[MAX_LINK],O[MAX_LINK],S[MAX_C],H[MAX_R]; //C&O代表列&行,S每一列的节点数,H每一行的第一个节点 13 int NodeNumber,RecordNumber; //用来指向节点 14 int state[MAX_SUDOKU],ans[MAX_SUDOKU],record[MAX_SUDOKU]; 15 //////////////////////Dancing Links模版////////////////////// 16 void init(void); //Dancing Links的抽象链表初始化 17 void insert(int,int); //在链表的一个位置中添加标记 18 void remove(int); //删除一列,同时删除这一列中的行 19 void resume(int); //恢复一列,同时恢复这一列中的行 20 //////////////////////Dancing Links模版////////////////////// 21 bool input(void) 22 { 23 char buffer[SIZE+1][SIZE+1];//留一个空间 24 if(scanf("%s",buffer[0])==EOF) return false; 25 for(int i=1;i<SIZE;i++) 26 scanf("%s",buffer[i]); 27 memset(state,0,sizeof(state)); 28 for(int i=0;i<SIZE;i++) 29 for(int j=0;j<SIZE;j++) 30 { 31 if(buffer[i][j]!='0') 32 state[i*SIZE+j]=buffer[i][j]-'0'; 33 } 34 return true; 35 } 36 37 void add(int i,int j,int k) 38 { 39 int row=i*MAX_SUDOKU+j*SIZE+k; 40 insert(row,i*SIZE+j+1);//注意 41 insert(row,i*SIZE+k+MAX_SUDOKU); 42 insert(row,j*SIZE+MAX_SUDOKU*2+k); 43 insert(row,(i/XSIZE*XSIZE +j/XSIZE)*SIZE+MAX_SUDOKU*3+k); 44 } 45 46 void build(void) 47 { 48 int pos,row; 49 for(int i=0;i<SIZE;i++) 50 for(int j=0;j<SIZE;j++) 51 { 52 pos=i*SIZE+j; 53 if(state[pos]!=0) 54 { 55 add(i,j,state[pos]); 56 } 57 else if(state[pos]==0) 58 { 59 for(int k=1;k<=SIZE;k++) 60 { 61 add(i,j,k); 62 } 63 } 64 } 65 } 66 67 bool dfs(int k) 68 { 69 if(!R[0]) 70 { 71 RecordNumber=k; 72 return true; 73 } 74 int count=~(1<<31),c; 75 for(int i=R[0];i;i=R[i]) 76 { 77 if(S[i]<count) 78 { 79 count=S[i]; 80 c=i; 81 if(count==1) 82 break; 83 } 84 } 85 remove(c); 86 for(int i=D[c];i!=c;i=D[i]) 87 { 88 for(int j=R[i];j!=i;j=R[j]) 89 { 90 remove(C[j]); 91 } 92 record[k]=O[i]; 93 if(dfs(k+1)) 94 return true; 95 for(int j=L[i];j!=i;j=L[j]) 96 { 97 resume(C[j]); 98 } 99 } 100 resume(c); 101 return false; 102 } 103 104 void output(void) 105 { 106 for(int i=0;i<RecordNumber;i++) 107 { 108 ans[(record[i]-1)/SIZE]=(record[i]-1)%SIZE+1; 109 } 110 for(int i=0;i<SIZE;i++) 111 { 112 for(int j=0;j<SIZE;j++) 113 printf("%-2d",ans[i*SIZE+j]); 114 printf("\n"); 115 } 116 } 117 118 int main() 119 { 120 while(input()) 121 { 122 time_t start=clock(); 123 init(); 124 build(); 125 dfs(0); 126 output(); 127 printf("Time:%ldMs\n",clock()-start); 128 } 129 return 0; 130 } 131 132 //////////////////////Dancing Links模版////////////////////// 133 void init(void) 134 { 135 for(int i=0;i<=MAX_C;i++) 136 { 137 L[i]=i-1; 138 R[i]=i+1; 139 U[i]=i; 140 D[i]=i; 141 C[i]=i; 142 O[i]=0; 143 } 144 L[0]=MAX_C; 145 R[MAX_C]=0; 146 NodeNumber=MAX_C+1; 147 memset(S,0,sizeof(S)); 148 memset(H,0,sizeof(H)); 149 } 150 151 void insert(int i,int j) 152 { 153 if(H[i]) 154 { 155 L[NodeNumber]=L[H[i]]; 156 R[NodeNumber]=H[i]; 157 L[R[NodeNumber]]=NodeNumber; 158 R[L[NodeNumber]]=NodeNumber; 159 } 160 else 161 { 162 L[NodeNumber]=NodeNumber; 163 R[NodeNumber]=NodeNumber; 164 H[i]=NodeNumber; 165 } 166 U[NodeNumber]=U[j]; 167 D[NodeNumber]=j; 168 U[D[NodeNumber]]=NodeNumber; 169 D[U[NodeNumber]]=NodeNumber; 170 C[NodeNumber]=j; 171 O[NodeNumber]=i; 172 S[j]++; 173 NodeNumber++; 174 } 175 176 void remove(int c) 177 { 178 L[R[c]]=L[c]; 179 R[L[c]]=R[c]; 180 for(int i=D[c];i!=c;i=D[i]) 181 { 182 for(int j=R[i];j!=i;j=R[j]) 183 { 184 U[D[j]]=U[j]; 185 D[U[j]]=D[j]; 186 S[C[j]]--; 187 } 188 } 189 } 190 191 void resume(int c) 192 { 193 for(int i=U[c];i!=c;i=U[i]) 194 { 195 for(int j=L[i];j!=i;j=L[j]) 196 { 197 U[D[j]]=j; 198 D[U[j]]=j; 199 S[C[j]]++; 200 } 201 } 202 L[R[c]]=c; 203 R[L[c]]=c; 204 } 205 /* 206 070680050 207 000000001 208 409507000 209 560000340 210 000000000 211 034000017 212 000703804 213 300000000 214 090015030 215 */
——现在的努力是为了小时候吹过的牛B!!