37 Sudoku Solver

Hard

Write a program to solve a Sudoku puzzle by filling the empty cells.

A sudoku solution must satisfy all of the following rules:

  1. Each of the digits 1-9 must occur exactly once in each row.
  2. Each of the digits 1-9 must occur exactly once in each column.
  3. Each of the the digits 1-9 must occur exactly once in each of the 9 3x3 sub-boxes of the grid.

Empty cells are indicated by the character '.'.

Unsolved Sudoku
A sudoku puzzle…

Solved Sudoku
…and its solution numbers marked in red.

Note:

  • The given board contain only digits 1-9 and the character '.'.
  • You may assume that the given Sudoku puzzle will have a single unique solution.
  • The given board size is always 9x9.

编写一个程序,通过已填充的空格来解决数独问题。

一个数独的解法需遵循如下规则

  1. 数字 1-9 在每一行只能出现一次。
  2. 数字 1-9 在每一列只能出现一次。
  3. 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。

空白格用 '.' 表示。

Sudoku

一个数独。

Sudoku

答案被标成红色。

Note:

  • 给定的数独序列只包含数字 1-9 和字符 '.'
  • 你可以假设给定的数独只有唯一解。
  • 给定数独永远是 9x9 形式的。

想法

这道题想了好久,最后看了网上的答案(sigh),总结了一下,基本就是HashMap+DFS,首先用三个数组存储数独中每一行、每一列、每一个方块中数字的占用情况,然后用回溯法DFS遍历一遍即可。要注意方块的计算公式为$i / 3 \times 3 + j / 3$。写的过程中遇到好多笔误,调了很多遍才能跑通(sigh)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#include <iostream>
#include <cstring>
#include <vector>

using namespace std;

bool row[9][9];
bool column[9][9];
bool box[9][9];
bool done;

void dfs(vector<vector<char> > &board, int i, int j)
{
if (i > 8) {
done = true;
return;
}
if (board[i][j] == '.') {
for (int n = 0; n < 9; n++) {
if (!(row[i][n] || column[j][n] || box[(i / 3) * 3 + j / 3][n])) {
board[i][j] = n + '1';
row[i][n] = column[j][n] = box[(i / 3) * 3 + j / 3][n] = true;
if (j >= 8) {
dfs(board, i + 1, 0);
}
else {
dfs(board, i, j + 1);
}
if (done)
break;
board[i][j] = '.';
row[i][n] = column[j][n] = box[(i / 3) * 3 + j / 3][n] = false;
}
}
}
else {
if (j >= 8) {
dfs(board, i + 1, 0);
}
else {
dfs(board, i, j + 1);
}
}
}

void solveSudoku(vector<vector<char> > &board)
{
memset(row, 0, 9 * 9 * sizeof(bool));
memset(column, 0, 9 * 9 * sizeof(bool));
memset(box, 0, 9 * 9 * sizeof(bool));
done = false;

int num = 0;

//Initialize

for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if (board[i][j] != '.') {
num = board[i][j] - '1';
row[i][num] = true;
column[j][num] = true;
box[(i / 3) * 3 + j / 3][num] = true;
}
}
}
dfs(board, 0, 0);
}

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×