pku 3074 3076 Sudoku 问题

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

Description

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

.2738..1.
.1...6735
.......29
3.5692.8.
.........
.6.1745.3
64.......
9518...7.
.8..6534.

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代码:
ContractedBlock.gif ExpandedBlockStart.gif 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 }

转载于:https://www.cnblogs.com/183zyz/archive/2011/08/09/2132596.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值