pku 3074 3076 Sudoku 问题

Sudoku
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 5624 Accepted: 1718

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了。
对于9*9的数独而言 首先需要建这么多9*9 + 9*9 + 9*9 + 9*9列, 因为数独问题是精确覆盖,所以需要加许多列进行限制。
第一个9*9表示图中的所给的81个小方格,每个方格里需要放一个数。
第二个9*9表示9行,然后每行里面要有9个不同的数。
第三个9*9表示9列,然后每列里面要有9个不同的数。
第四个9*9表示9个3*3的方格,每个3*3的方格里面要有9个不同的数。
然后建行,如果是一个“.”,则需要建9行,因为有9个可能的数。
如果是一个给定的数,则只需建一行。
然后把每一行与 所对应的列  建一个关系就行了。
主要是注意细节问题。。 
这种Dancing Links应该存在很多优化的,比如建行的时候,如果该“.”已经可以判断出来不能放某些元素了,那就可以少建一些。
3076题,16*16的数独,需要建4* 16*16列,其他的基本类似。
贴下3074代码:
View Code
  1 # include<stdio.h>
2 # include<string.h>
3 # define RR 750
4 # define CC 350
5 # define V RR*CC
6 int U[V],D[V];
7 int L[V],R[V];
8 int C[V],ROW[V];
9 int H[RR],S[CC];
10 int size;
11 char s[10][10];
12 int hash1[RR],hash2[RR],OK[87];
13 char hash[RR];
14 void Link(int r,int c)
15 {
16 S[c]++;C[size]=c;
17 ROW[size]=r;
18 U[size]=U[c];D[U[c]]=size;
19 D[size]=c;U[c]=size;
20 if(H[r]==-1) H[r]=L[size]=R[size]=size;
21 else
22 {
23 L[size]=L[H[r]];R[L[H[r]]]=size;
24 R[size]=H[r];L[H[r]]=size;
25 }
26 size++;
27 }
28 void remove(int c)
29 {
30 int i,j;
31 L[R[c]]=L[c];
32 R[L[c]]=R[c];
33 for(i=D[c];i!=c;i=D[i])
34 {
35 for(j=R[i];j!=i;j=R[j])
36 {
37 S[C[j]]--;
38 U[D[j]]=U[j];
39 D[U[j]]=D[j];
40 }
41 }
42 }
43 void resume(int c)
44 {
45 int i,j;
46 for(i=U[c];i!=c;i=U[i])
47 {
48 for(j=L[i];j!=i;j=L[j])
49 {
50 S[C[j]]++;
51 U[D[j]]=D[U[j]]=j;
52 }
53 }
54 R[L[c]]=L[R[c]]=c;
55 }
56 int Dance(int k)
57 {
58 int i,j,Min,c;
59 if(!R[0]) return 1;
60 for(Min=RR,i=R[0];i;i=R[i])
61 if(Min>S[i]) Min=S[i],c=i;
62 remove(c);
63 for(i=D[c];i!=c;i=D[i])
64 {
65 for(j=R[i];j!=i;j=R[j])
66 remove(C[j]);
67 OK[k]=ROW[i];
68 if(Dance(k+1)) return 1;
69 for(j=L[i];j!=i;j=L[j])
70 resume(C[j]);
71 }
72 resume(c);
73 return 0;
74 }
75 int main()
76 {
77 int i,j,k,r;
78 char st[87];
79 while(gets(st))
80 {
81 if(st[0]=='e') break;
82 i=0;
83 for(j=1;j<=9;j++)
84 for(k=1;k<=9;k++)
85 s[j][k]=st[i++];
86 for(i=0;i<=324;i++)
87 {
88 S[i]=0;
89 D[i]=U[i]=i;
90 L[i+1]=i;R[i]=i+1;
91 }R[324]=0;
92 size=325;
93 r=0;
94 memset(H,-1,sizeof(H));
95 for(i=1;i<=9;i++)
96 {
97 for(j=1;j<=9;j++)
98 {
99 if(s[i][j]!='.')
100 {
101 r++;
102 hash1[r]=i;
103 hash2[r]=j;
104 hash[r]=s[i][j];
105 Link(r,(i-1)*9+j);
106 Link(r,81+(i-1)*9+s[i][j]-'0');
107 Link(r,162+(j-1)*9+s[i][j]-'0');
108 Link(r,243+ ((i-1)/3)*27 + ((j-1)/3)*9 + s[i][j]-'0');
109 }
110 else
111 {
112 for(k=1;k<=9;k++)
113 {
114 r++;
115 hash1[r]=i;
116 hash2[r]=j;
117 hash[r]=k+'0';
118 Link(r,(i-1)*9+j);
119 Link(r,81+(i-1)*9+k);
120 Link(r,162+(j-1)*9+k);
121 Link(r,243+ ((i-1)/3)*27 + ((j-1)/3)*9 + k );
122 }
123 }
124 }
125 }
126 Dance(0);
127 for(i=0;i<81;i++)
128 s[hash1[OK[i]]][hash2[OK[i]]]=hash[OK[i]];
129 for(i=1;i<=9;i++)
130 for(j=1;j<=9;j++)
131 printf("%d",s[i][j]-'0');
132 puts("");
133 }
134 return 0;
135 }

你可能感兴趣的:(sudo)