A Sudoku grid is a
16 x 16 grid of cells grouped in sixteen 4 x 4 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 grid cells with letters
from A to P such that each letter from the grid occurs once only in the line, the column, and the 4 x 4 square it occupies. The initial content of the grid satisfies the constraints mentioned above and guarantees a unique solution.
Figure 1. Sudoku
|
| A |
|
|
|
| C |
|
|
|
|
| O |
| I |
| J |
|
| A |
| B |
| P |
| C | G | F |
| H |
|
|
| D |
|
| F |
| I |
| E |
|
|
|
| P |
|
| G |
| E | L |
| H |
|
|
|
| M |
| J |
|
|
|
|
|
| E |
|
|
|
| C |
|
| G |
|
|
|
| I |
|
| K |
| G | A |
| B |
|
|
| E |
| J |
D |
| G | P |
|
| J |
| F |
|
|
|
| A |
|
|
| E |
|
|
| C |
| B |
|
| D | P |
|
| O |
|
E |
|
| F |
| M |
|
| D |
|
| L |
| K |
| A |
| C |
|
|
|
|
|
|
|
| O |
| I |
| L |
|
H |
| P |
| C |
|
| F |
| A |
|
| B |
|
|
|
|
|
| G |
| O | D |
|
|
| J |
|
|
|
| H |
K |
|
|
| J |
|
|
|
| H |
| A |
| P |
| L |
|
| B |
|
| P |
|
| E |
|
| K |
|
| A |
|
| H |
|
| B |
|
| K |
|
| F | I |
| C |
|
|
|
| F |
|
|
| C |
|
| D |
|
| H |
| N |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
a) Sudoku grid
F | P | A | H | M | J | E | C | N | L | B | D | K | O | G | I |
O | J | M | I | A | N | B | D | P | K | C | G | F | L | H | E |
L | N | D | K | G | F | O | I | J | E | A | H | M | B | P | C |
B | G | C | E | L | K | H | P | O | F | I | M | A | J | D | N |
M | F | H | B | E | L | P | O | A | C | K | J | G | N | I | D |
C | I | L | N | K | D | G | A | H | B | M | O | P | E | F | J |
D | O | G | P | I | H | J | M | F | N | L | E | C | A | K | B |
J | E | K | A | F | C | N | B | G | I | D | P | L | H | O | M |
E | B | O | F | P | M | I | J | D | G | H | L | N | K | C | A |
N | C | J | D | H | B | A | E | K | M | O | F | I | G | L | P |
H | M | P | L | C | G | K | F | I | A | E | N | B | D | J | O |
A | K | I | G | N | O | D | L | B | P | J | C | E | F | M | H |
K | D | E | M | J | I | F | N | C | H | G | A | O | P | B | L |
G | L | B | C | D | P | M | H | E | O | N | K | J | I | A | F |
P | H | N | O | B | A | L | K | M | J | F | I | D | C | E | G |
I | A | F | J | O | E | C | G | L | D | P | B | H | M | N | K |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
b) Solution
Write a Sudoku playing program that reads data sets from a text file.
Each data set encodes a grid and contains 16 strings on 16 consecutive lines as shown in figure 2. The i-th string stands for the i-th
line of the grid, is 16 characters long, and starts from the first
position of the line. String characters are from the set {A,B,...,P,-}, where `-' (minus) designates empty grid cells. The data sets are separated by single empty lines and terminate with an end of file.
The program prints the solution of the input encoded grids in the same format and order as used for input.
--A----C-----O-I
-J--A-B-P-CGF-H-
--D--F-I-E----P-
-G-EL-H----M-J--
----E----C--G---
-I--K-GA-B---E-J
D-GP--J-F----A--
-E---C-B--DP--O-
E--F-M--D--L-K-A
-C--------O-I-L-
H-P-C--F-A--B---
---G-OD---J----H
K---J----H-A-P-L
--B--P--E--K--A-
-H--B--K--FI-C--
--F---C--D--H-N-
FPAHMJECNLBDKOGI
OJMIANBDPKCGFLHE
LNDKGFOIJEAHMBPC
BGCELKHPOFIMAJDN
MFHBELPOACKJGNID
CILNKDGAHBMOPEFJ
DOGPIHJMFNLECAKB
JEKAFCNBGIDPLHOM
EBOFPMIJDGHLNKCA
NCJDHBAEKMOFIGLP
HMPLCGKFIAENBDJO
AKIGNODLBPJCEFMH
KDEMJIFNCHGAOPBL
GLBCDPMHEONKJIAF
PHNOBALKMJFIDCEG
IAFJOECGLDPBHMNK
Dancing Links 實作數獨,至於 DLX 是什麼結構,上網查一下唄。
此外題目忘了說明, "Output a empty blank line between test cases."
#include<stdio.h>
#include<stdlib.h>
#define Maxv 100000
struct DacingLinks {
int left, right;
int up, down;
int data, ch, rh;
}DL[1000001 + 3001];
int s[2001], o[2001], head, size, time;
int n, m, a, b, c, tn;
void Remove(int c) {
DL[DL[c].right].left = DL[c].left;
DL[DL[c].left].right = DL[c].right;
int i, j;
for(i = DL[c].down; i != c; i = DL[i].down) {
for(j = DL[i].right; j != i; j = DL[j].right) {
DL[DL[j].down].up = DL[j].up;
DL[DL[j].up].down = DL[j].down;
s[DL[j].ch]--;
}
}
}
void Resume(int c) {
int i, j;
for(i = DL[c].down; i != c; i = DL[i].down) {
for(j = DL[i].left; j != i; j = DL[j].left) {
DL[DL[j].down].up = j;
DL[DL[j].up].down = j;
s[DL[j].ch]++;
}
}
DL[DL[c].right].left = c;
DL[DL[c].left].right = c;
}
void Print_board(int k) {
static int set[512], a, b;
for(a = 0; a < k; a++) {
set[DL[o[a]].data] = DL[o[a]].rh+1;
}
for(a = 0; a < n; a++) {
for(b = 0; b < n; b++) {
printf("%c", set[a*16+b]+'A'-1);
}
puts("");
}
}
void DFS(int k) {
if(time) return ;
if(DL[head].right == head) {
Print_board(k);
time++;
return;
}
int t = Maxv, c, i, j;
for(i = DL[head].right; i != head; i = DL[i].right) {
if(s[i] < t) {
t = s[i], c = i;
}
}
Remove(c);
for(i = DL[c].down; i != c; i = DL[i].down) {
o[k] = i;
for(j = DL[i].right; j != i; j = DL[j].right)
Remove(DL[j].ch);
DFS(k+1);
for(j = DL[i].left; j != i; j = DL[j].left)
Resume(DL[j].ch);
}
Resume(c);
}
int new_node(int up, int down, int left, int right) {
DL[size].up = up, DL[size].down = down;
DL[size].left = left, DL[size].right = right;
DL[up].down = DL[down].up = DL[left].right = DL[right].left = size;
return size++;
}
void new_row(int n, int Row[], int rh, int set) {
int a, r, row = -1, k;
for(a = 0; a < n; a++) {
r = Row[a];
DL[size].ch = r, DL[size].data = set, s[r]++;
if(row == -1) {
row = new_node(DL[DL[r].ch].up, DL[r].ch, size, size);
DL[row].rh = rh;
}else {
k = new_node(DL[DL[r].ch].up, DL[r].ch, DL[row].left, row);
DL[k].rh = rh;
}
}
}
void init(int m) {
size = 0;
head = new_node(0, 0, 0, 0);
int i;
for(i = 1; i <= m; i++) {
new_node(i, i, DL[head].left, head);
DL[i].ch = i, s[i] = 0;
}
}
main() {
int map[20][20], Row[256], t, i;
char g[20][20], first = 0;
while(scanf("%s", g[0]) == 1) {
for(i = 1; i < 16; i++)
scanf("%s", g[i]);
n = 4;
tn = n, n *= n, m = n*n*4, init(m);
for(a = 0; a < n; a++)
for(b = 0; b < n; b++) {
if(g[a][b] == '-')
map[a][b] = 0;
else
map[a][b] = g[a][b]-'A'+1;
if(map[a][b] == 0) {
for(c = 0; c < n; c++) {
t = 0;
Row[t++] = a*n + b + 1;
Row[t++] = n*n + a*n + c + 1;
Row[t++] = 2*n*n+ b*n + c + 1;
Row[t++] = 3*n*n+ (a/tn*tn + b/tn)*n + c + 1;
new_row(t, Row, c, a*n+b);
/*printf("%d ", a*9 + b + 1);/*原始牌面上的標記
printf("%d ", 81 + a*9 + c + 1);/*行上1~9的標記
printf("%d ", 162+ b*9 + c + 1);/*列上1~9的標記
printf("%d ", 243+ (a/3*3 + b/3)*9 + c + 1);/*方格中1~9的標記
puts("");*/
}
} else {
c = map[a][b]-1, t = 0;
Row[t++] = a*n + b + 1;
Row[t++] = n*n + a*n + c + 1;
Row[t++] = 2*n*n+ b*n + c + 1;
Row[t++] = 3*n*n+ (a/tn*tn + b/tn)*n + c + 1;
new_row(t, Row, c, a*n+b);
/*printf("%d ", a*9 + b + 1);/*原始牌面上的標記
printf("%d ", 81 + a*9 + c + 1);/*行上1~9的標記
printf("%d ", 162+ b*9 + c + 1);/*列上1~9的標記
printf("%d ", 243+ (a/3*3 + b/3)*9 + c + 1);/*方格中1~9的標記
puts("");*/
}
}
if(first) puts("");
first = 1;
time = 0, DFS(0);
}
return 0;
}
文章定位: