POJ 3074 Sudoku (DLX)

Sudoku
Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u
Appoint description: 

Description

In the game of Sudoku, you are given a large 9 × 9 grid divided into smaller 3 × 3 subgrids. For example,

. 2 7 3 8 . . 1 .
. 1 . . . 6 7 3 5
. . . . . . . 2 9
3 . 5 6 9 2 . 8 .
. . . . . . . . .
. 6 . 1 7 4 5 . 3
6 4 . . . . . . .
9 5 1 8 . . . 7 .
. 8 . . 6 5 3 4 .

Given some of the numbers in the grid, your goal is to determine the remaining numbers such that the numbers 1 through 9 appear exactly once in (1) each of nine 3 × 3 subgrids, (2) each of the nine rows, and (3) each of the nine columns.

Input

The input test file will contain multiple cases. Each test case consists of a single line containing 81 characters, which represent the 81 squares of the Sudoku grid, given one row at a time. Each character is either a digit (from 1 to 9) or a period (used to indicate an unfilled square). You may assume that each puzzle in the input will have exactly one solution. The end-of-file is denoted by a single line containing the word “end”.

Output

For each test case, print a line representing the completed Sudoku puzzle.

Sample Input

.2738..1..1...6735.......293.5692.8...........6.1745.364.......9518...7..8..6534.
......52..8.4......3...9...5.1...6..2..7........3.....6...1..........7.4.......3.
end

Sample Output

527389416819426735436751829375692184194538267268174593643217958951843672782965341
416837529982465371735129468571298643293746185864351297647913852359682714128574936




用dancing links解数独,DLX专题的终极目标,手机上的数独玩了两天后终于A了,等下把记录用这个程序刷一遍,想象下小伙伴看到我最高难度下的耗时记录的表情,啊哈哈~~
难点在于怎么建立模型,一共有9行,每行有9个数字,所以就是9 * 9,同理,列也是9 * 9,小格子也是有9个,每个也是9个数字,所以也是9 * 9,另外整个图有9 * 9 = 81的格子。所以要覆盖的列就是 9 * 9 + 9 * 9 + 9 * 9 + 81。至于行,一共有81个格子,每个格子有9种取法,所以就有81 * 9行,行和列相乘就是开的数组的大小。还有个剪枝要注意下,如果某个格子的数字已经给出,那么这一行,这一列,这一个小格子,就没必要再填这个数了,不剪枝的话会T。
  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <string>
  5 #include <cstdlib>
  6 #include <cmath>
  7 #include <map>
  8 #include <cctype>
  9 using    namespace    std;
 10 
 11 const    int    HEAD = 0;
 12 const    int    SIZE = (81 * 9) * (81 * 4);
 13 const    int    COL = 81 * 4;
 14 int    U[SIZE],D[SIZE],L[SIZE],R[SIZE],S[SIZE],C[SIZE],N[SIZE],P_H[SIZE],P_C[SIZE];
 15 int    COUNT;
 16 int    TEMP[100][100];
 17 bool    VIS_I[15][15],VIS_J[15][15],VIS_G[15][15];
 18 struct    Node
 19 {
 20     int    i;
 21     int    j;
 22     int    num;
 23 }ANS[100];
 24 
 25 void    ini(void);
 26 void    link(int,int,int,int,int,int,int);
 27 bool    dancing(int);
 28 void    remove(int);
 29 void    resume(int);
 30 void    debug(int);
 31 int    main(void)
 32 {
 33     char    s[1000];
 34     while(scanf(" %s",s + 1) && strcmp(s + 1,"end"))
 35     {
 36         ini();
 37         for(int i = 1;i <= 9;i ++)
 38             for(int j = 1;j <= 9;j ++)
 39             {
 40                 int    k = s[(i - 1) * 9 + j];
 41                 int    c_1,c_2,c_3,c_4;
 42                 if(k != '.')
 43                 {
 44                     VIS_I[i][k - '0'] = VIS_J[j][k - '0'] = true;
 45                     VIS_G[(i - 1) / 3 * 3 + (j - 1) / 3 + 1][k - '0'] = true;
 46                     c_1 = 81 * 0 + (i - 1) * 9 + k - '0';
 47                     c_2 = 81 * 1 + (j - 1) * 9 + k - '0';
 48                     c_3 = 81 * 2 + ((i - 1) / 3 * 3 + (j - 1) / 3) * 9 + k - '0';
 49                     c_4 = 81 * 3 + (i - 1) * 9 + j;
 50                     link(c_1,c_2,c_3,c_4,k - '0',i,j);
 51                 }
 52             }
 53 
 54         for(int i = 1;i <= 9;i ++)
 55             for(int j = 1;j <= 9;j ++)
 56             {
 57                 if(s[(i - 1) * 9 + j] != '.')
 58                     continue;
 59                 int    c_1,c_2,c_3,c_4;
 60                 for(int k = 1;k <= 9;k ++)
 61                 {
 62                     if(VIS_I[i][k] || VIS_J[j][k] || 
 63                             VIS_G[(i - 1) / 3 * 3 + (j - 1) / 3 + 1][k])
 64                         continue;
 65                     c_1 = 81 * 0 + (i - 1) * 9 + k;
 66                     c_2 = 81 * 1 + (j - 1) * 9 + k;
 67                     c_3 = 81 * 2 + ((i - 1) / 3 * 3 + (j - 1) / 3) * 9 + k;
 68                     c_4 = 81 * 3 + (i - 1) * 9 + j;
 69                     link(c_1,c_2,c_3,c_4,k,i,j);
 70                 }
 71             }
 72         dancing(0);
 73     }
 74 
 75     return    0;
 76 }
 77 
 78 void    ini(void)
 79 {
 80     L[HEAD] = COL;
 81     R[HEAD] = 1;
 82     for(int    i = 1;i <= COL;i ++)
 83     {
 84         L[i] = i - 1;
 85         R[i] = i + 1;
 86         U[i] = D[i] = C[i] = i;
 87         S[i] = 0;
 88     }
 89     R[COL] = HEAD;
 90 
 91     fill(&VIS_I[0][0],&VIS_I[12][12],false);
 92     fill(&VIS_J[0][0],&VIS_J[12][12],false);
 93     fill(&VIS_G[0][0],&VIS_G[12][12],false);
 94     COUNT = COL + 1;
 95 }
 96 
 97 void    link(int c_1,int c_2,int c_3,int c_4,int num,int r,int c)
 98 {
 99     int    first = COUNT;
100     int    col;
101 
102     for(int i = 0;i < 4;i ++)
103     {
104         switch(i)
105         {
106             case    0:col = c_1;break;
107             case    1:col = c_2;break;
108             case    2:col = c_3;break;
109             case    3:col = c_4;break;
110         }
111 
112         L[COUNT] = COUNT - 1;
113         R[COUNT] = COUNT + 1;
114         U[COUNT] = U[col];
115         D[COUNT] = col;
116 
117         D[U[col]] = COUNT;
118         U[col] = COUNT;
119         C[COUNT] = col;
120         N[COUNT] = num;
121         P_H[COUNT] = r;
122         P_C[COUNT] = c;
123         S[col] ++;
124         COUNT ++;
125     }
126     L[first] = COUNT - 1;
127     R[COUNT - 1] = first;
128 }
129 
130 bool    dancing(int k)
131 {
132     if(R[HEAD] == HEAD)
133     {
134         for(int i = 0;i < k;i ++)
135             TEMP[ANS[i].i][ANS[i].j] = ANS[i].num;
136         int    count = 0;
137         for(int i = 1;i <= 9;i ++)
138             for(int j = 1;j <= 9;j ++)
139                 printf("%d",TEMP[i][j]);
140         puts("");
141         return    true;
142     }
143 
144     int    c = R[HEAD];
145     for(int i = R[HEAD];i != HEAD;i = R[i])
146         if(S[c] > S[i])
147             c = i;
148 
149     remove(c);
150     for(int i = D[c];i != c;i = D[i])
151     {
152         ANS[k].i = P_H[i];
153         ANS[k].j = P_C[i];
154         ANS[k].num = N[i];
155         for(int j = R[i];j != i;j = R[j])
156             remove(C[j]);
157         if(dancing(k + 1))
158             return    true;
159         for(int j = L[i];j != i;j = L[j])
160             resume(C[j]);
161     }
162     resume(c);
163 
164     return    false;
165 }
166 
167 void    remove(int c)
168 {
169     L[R[c]] = L[c];
170     R[L[c]] = R[c];
171     for(int i = D[c];i != c;i = D[i])
172         for(int j = R[i];j != i;j = R[j])
173         {
174             D[U[j]] = D[j];
175             U[D[j]] = U[j];
176             S[C[j]] --;
177         }
178 }
179 
180 void    resume(int c)
181 {
182     L[R[c]] = c;
183     R[L[c]] = c;
184     for(int i = D[c];i != c;i = D[i])
185         for(int j = L[i];j != i;j = L[j])
186         {
187             D[U[j]] = j;
188             U[D[j]] = j;
189             S[C[j]] ++;
190         }
191 }

 

posted @ 2015-04-23 13:26  Decouple  阅读(333)  评论(0编辑  收藏  举报