POJ 3074 Sudoku (DLX)

Sudoku
Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u
Submit  Status  Practice  POJ 3074
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 }

 

你可能感兴趣的:(sudo)