编写一个程序,通过已填充的空格来解决数独问题。
一个数独的解法需遵循如下规则:
数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。
空白格用 '.' 表示。
采用深度搜索的方式,如果非空格就需要进行n+1收拾,如果搜索成功则采用book数组标记,shuo搜索失败需要回退对数独的修改,具体的实现见代码。
#include<iostream>
#include<string>
#include<vector>
#include<memory.h>
using namespace::std;
class Solution {
public:
void solveSudoku(vector<vector<char>>& board) {
int row_len = board.size();
int col_len = board[0].size();
cout<<row_len<<" "<<col_len<<endl;
bool *book = (bool *)malloc(row_len * col_len * sizeof(bool));
memset(book, 0, row_len * col_len*sizeof(bool));
DFS(board, book, 0);
Output(board);
free(book);
}
void Output(vector<vector<char>>& board)
{
for(auto str: board)
{
for(auto c: str)
{
cout<<c<<' ';
}
cout<<endl;
}
}
bool checkNumOk(vector<vector<char>>& board, int n, const char key)
{
bool bRet = false;
int row_len = board.size();
int col_len = board[0].size();
/* 判断n所在的行是否合法 */
for(int j = 0; j < col_len; j++)
{
int i = n / col_len;
if(board[i][j] == key)
{
return bRet;
}
}
/* 判断n所在的列是否合法 */
for(int i = 0; i < row_len; i++)
{
int j = n % col_len;
if(board[i][j] == key)
{
return bRet;
}
}
/* x为n所在的小九宫格左顶点竖坐标 */
int x = n / 9 / 3 * 3;
/* y为n所在的小九宫格左顶点横坐标 */
int y = n % 9 / 3 * 3;
/* 判断n所在的小九宫格是否合法 */
for (int i = x; i < x + 3; i++)
{
for (int j = y; j < y + 3; j++)
{
if (board[i][j] == key)
{
return bRet;
}
}
}
return true;
}
bool DFS(vector<vector<char>>& board, bool *book , int n)
{
int row_len = board.size();
int col_len = board[0].size();
if (n >= row_len * col_len)
{
return true;
}
if(board[n / col_len][n % col_len] != '.')
{
book[n] = true;
if(DFS(board, book, n + 1))
{
return true;
}
}
else
{
for(int i = 0; i < 9; i++)
{
char ch = i + '1';
if(checkNumOk(board, n, ch) && !book[n])
{
board[n / col_len][n % col_len] = ch;
Output(board);
cout<<endl;
book[n] = true;
if(DFS(board, book, n + 1))
{
return true;
}
/* 如果构造不成功,还原当前位 */
board[n / col_len][n % col_len] = '.';
book[n] = false;
}
}
}
return false;
}
};
int main()
{
vector<vector<char> > board = {
{'5', '3', '.', '.', '7', '.', '.', '.', '.'},
{'6', '.', '.', '1', '9', '5', '.', '.', '.'},
{'.', '9', '8', '.', '.', '.', '.', '6', '.'},
{'8', '.', '.', '.', '6', '.', '.', '.', '3'},
{'4', '.', '.', '8', '.', '3', '.', '.', '1'},
{'7', '.', '.', '.', '2', '.', '.', '.', '6'},
{'.', '6', '.', '.', '.', '.', '2', '8', '.'},
{'.', '.', '.', '4', '1', '9', '.', '.', '5'},
{'.', '.', '.', '.', '8', '.', '.', '7', '9'}
};
Solution abj;
abj.solveSudoku(board);
return 0;
}
1081

被折叠的 条评论
为什么被折叠?



