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 */

 

posted @ 2013-06-14 22:50  瓶哥  Views(296)  Comments(0Edit  收藏  举报