POJ 3074 Sudoku (DLX)

Sudoku

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

Submit Status Practice POJ 3074

Appoint description: 
System Crawler  (2015-04-18)

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 }
时间: 2024-08-25 04:48:17

POJ 3074 Sudoku (DLX)的相关文章

poj 3074 Sudoku dlx解数独

分析: dlx是从数据结构角度优化01矩阵精确覆盖和重复覆盖的数据结构,它用十字链表只存贮矩阵中的非0元,而01矩阵精确覆盖dfs过程中矩阵会越来越稀疏而且每次恢复现场会浪费大量时间,dlx恰好能解决这两个问题.本题关键是将数独问题转化为01矩阵精确覆盖.数独转化为精确覆盖问题的方法还是参照Knuth的论文,如果读取到一个格子是空的,那么加9行,分别表示这个格子填1到9这9个数字,如果读取到的格子是一个数字,那么就加一行就可以了,然后列有9*9*4列,前81列表示这一行表示填的是第i行第j列的格

POJ 3074 Sudoku DLX精确覆盖

DLX精确覆盖.....模版题 Sudoku Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8336   Accepted: 2945 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 . .

(简单) POJ 3074 Sudoku, DLX+精确覆盖。

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

poj 3074 Sudoku(Dancing Links)

Sudoku Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8152   Accepted: 2862 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 . . .

poj 3076 Sudoku dlx解数独

16*16的数独,类似poj 3074. //poj 3076 //sep9 #include <cstdio> #include <cstdlib> #define INT_MAX 2147483647 using namespace std; const int col_num=16*16*4; const int row_num=16*16*16+10; const int head=0; const int MAX=row_num*4+col_num+10; const i

(简单) POJ 3076 Sudoku , DLX+精确覆盖。

Description A Sudoku grid is a 16x16 grid of cells grouped in sixteen 4x4 squares, where some cells are filled with letters from A to P (the first 16 capital letters of the English alphabet), as shown in figure 1a. The game is to fill all the empty g

POJ 3047 Sudoku DLX精确覆盖

DLX精确覆盖.....模版题 Sudoku Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8336   Accepted: 2945 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 . .

POJ 3076 Sudoku DLX精确覆盖

DLX精确覆盖模版题..... Sudoku Time Limit: 10000MS   Memory Limit: 65536K Total Submissions: 4416   Accepted: 2143 Description A Sudoku grid is a 16x16 grid of cells grouped in sixteen 4x4 squares, where some cells are filled with letters from A to P (the fi

POJ 3074 Sudoku 舞蹈链

#include <cstdio> #include <iostream> #include <algorithm> #include <queue> #include <stack> #include <cstdlib> #include <cmath> #include <set> #include <map> #include <vector> #include <cstri