您的位置:首页 > 其它

Leetcode (37) Sudoku Solver

2016-10-10 22:58 393 查看
Write a program to solve a Sudoku puzzle by filling the empty cells.

Empty cells are indicated by the character ‘.’.

You may assume that there will be only one unique solution.

题意:求解数独游戏,给定的board里面空缺的位置用’.’来表示,即board中的数字也是char类型

思路:不知道数独是不是像魔方那样有一定的求解公式,而回忆自己做数独题的过程中,往往都会找到一些必然确定的位置,先填上,再逐步完成游戏。而存在必然确定的位置,一般都是一些比较低级的数独,而高级一点的常常要尝试,若是找到矛盾就回到原来位置,逐步排除,最后完成。

实际上这就是一种深搜,失败则回溯修改再次尝试的策略,利用计算机的高速计算能力则可以不停地进行尝试,最终完成游戏。

而实际上,可以往里面添加一点策略,进而达到剪枝的效果。比如说,数独游戏的规则要保证每一行、每一列、每个九宫格内的数字都要不同,那么如果尝试的数字违反了这一规则,那么必然可以直接排除,就跟我们平时玩的时候一样,达到剪枝的效果。

PS: 实际上搜索顺序还会影响到求解速度,比如说,先填写数字比较多的行或者列,能够尽快排除掉错误答案,找到正解,还能进一步优化!

class Solution {
public:
void solveSudoku(vector<vector<char>>& board) {
memset(nums,0,sizeof(nums));
memset(nn,0,sizeof(nn));
for (int i=0;i<9;i++)
{
for (int j=0;j<9;j++)
{
int n;
if (board[i][j]=='.') n=0;
else n = board[i][j] - '0';
chart[i][j] = n;
nums[0][i]
= nums[1][j]
= nn[i / 3][j / 3]
= 1;
}
}
dfs(8,8);
for (int i=0;i<9;i++)
{
for (int j=0;j<9;j++)
{
board[i][j] = chart[i][j] + '0';
}
}
}
private:
int chart[10][10];
bool ok, nums[2][10][10], nn[3][3][10];
void dfs(int x, int y) {
if (chart[x][y] != 0) {
if (x == 0 && y == 0)ok = true;
else if (y == 0)dfs(x - 1, 8);
else dfs(x, y - 1);
}
else {
for (int i = 1; i <= 9; i++)
if (nums[0][x][i] == 0 && nums[1][y][i] == 0 && nn[x / 3][y / 3][i] == 0) {
nums[0][x][i] = nums[1][y][i] = nn[x / 3][y / 3][i] = 1;
chart[x][y] = i;
if (x == 0 && y == 0)ok = true;
else if (y == 0)dfs(x - 1, 8);
else dfs(x, y - 1);
if (ok) return;
nums[0][x][i] = nums[1][y][i] = nn[x / 3][y / 3][i] = 0;
chart[x][y] = 0;
}
}
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  leetcode