leetcode 37 数独问题的解答

leetcode 37 数独问题的解答

1.问题 请写一个程序来解决数独难题。
数独解决方案应该遵循以下三个规则:
1.每个数字1-9只能在每行中出现一次。
2.每个数字1-9只能在每列中出现一次。
3.每个数字1-9只能在网格的每个3x3子框中出现一次。
2.要求
·空格字符表示一个空的单元格。
·拼图板是一个长度为9的方阵
·保证输入板只有一个解决方案。
3.算法核心思想
本道题的思想和n皇后是比较相似,可以类比的是n皇后是在每一行,每一列,和两个斜 对角线上是有冲突的,数独是在每一列,每一行以及每个33的小方格当中是冲突的,而且在做算法的过程中都可以通过行优先的方式进行回溯,但是两个也有不同的地方,其中一点就 是n皇后在每一行只放置一个,但是数独是每一个位置都放置1-9的不同的数字。 在本道题当中,我使用的是通过行优先的方式,从一个矩阵的[0][0]位置开始,首先判断 在给出的数组当中这个位置是否是空格(即没有数字),如果没有数字,那么就从1-9逐一放 置数字,比如当我放置了一个1,于此同时,我要判断我放置的这个1是否能够满足我的每一 行每一列以及每个33的小方格上是否满足没有1,如果有1,那么就重新找2,如果2满足情 况,那么就是在这个位置上填2的基础上,在这一行上填其他的数字,如果填着填着发现在2 的基础上填这一行上的数字始终有不对的地方,那么进行返回,一直返回到刚刚填2的那个位 置,重新在这个位置上尝试3,以此类推,继续这样执行,如果发现,在某一行都填不出数字, 那么这个数独返回false无解,如果我的一行可以成功的填入数字,那么就是进行递归到下一 行再次重复上述的操作,直到进行到我的每一行都填完数字为止,当然如果不满足情况,那 么就是这个数独无解

分享代码

#include<iostream>
#include<vector>
using namespace std;


class solvesudoku //建立一个专门解决此类问题的类
{
public:
	bool Bactrack(vector<vector<char>>& board,int row,int col);//这是一个回溯函数
	bool isValid(vector<vector<char>>& board, int row, int col,char ch);//判断这个数字在行,列以及每个小方格上是否重复
};
bool solvesudoku::Bactrack(vector<vector<char>>& board, int row, int col) {
	if (col == 9)//列为9,换到下一行
		return Bactrack(board, row + 1, 0);
	if (row == 9)//行为9,说明已经结束,回溯成功,数独有解
		return true;
	//从第0行第0列开始进行回溯
	for (int i = row; i < 9; i++) 
	{
		for (int j = col; j < 9; j++)
		{
			if (board[i][j] != ' ')  
				//如果上面有数字,则跳到下一列
				return Bactrack(board, i, j + 1);
			for (char ch = '1'; ch <='9'; ch++) //在这个方格当中对数字都进行一次尝试
			{
				if (!isValid(board, i, j, ch))//每次填入一个数字就对这个数字进行判断
					continue;
				board[i][j] = ch;//如果判断成功,那么就填入这个数字
				if (Bactrack(board, i, j + 1))//判断成功的同时对这个位置的下一列进行判断,看看在这个数的基础上,这一行是否都成立
					return true;
				board[i][j] = ' ';//如果不成立,回溯换数字
			}
			return false;//如果这一行都回溯不成功,那么这个数独是无解的,返回错误
		}
	}
	return false;
}
bool solvesudoku::isValid(vector<vector<char>>& board, int row, int col, char ch) {
	for (int i = 0 ; i < 9; i++) 
	{
		if (board[row][i] == ch)//这一行上是否有相等的
			return false;
		if (board[i][col] == ch)//这一列上是否有相等的
			return false;
		if (board[3 * (row / 3) + i / 3][3 * (col / 3) + i % 3] == ch)//在分块的小方格上是否有相同的
			return false;
	}
	return true;
}
int main() {

	vector<vector<char>> vec;//设一个二维的数组
	solvesudoku Solution;
	vector<char>v;// 一维数组
	char tem;//方便提取输入的字符
	cout << "Input:" << endl;
	for (int i = 0; i < 9; i++)
	{
		v.clear();//进行一行的清除
		for (int j = 0; j < 9; j++)
		{
			while (1) {
				tem = getchar();
				if (tem >= '1' && tem <= '9' || tem == ' ')
					break;

			}
			v.push_back(tem);//压入一维数组
		}
		vec.push_back(v);//把一维数组压入二维数组
	}
	cout << endl;
	if (Solution.Bactrack(vec, 0, 0)) //带入函数当中,如果函数返回值为真,就输出这个结果
	{
		cout << "Output:" << endl;
		cout << endl;
		cout << "[";
		for (int i = 0; i < 9; i++) {
			cout << "[";
			for (int j = 0; j < 9; j++)
			{
				if(j!=8)
				cout << "\"" << vec[i][j] << "\",";
				else
					cout << "\"" << vec[i][j] << "\" ";
			}
			cout << "],";
			if(i!=8)
				cout << endl;
		}
		cout << "]";
	}
	else //如果返回值假,就输出error表示这个数独无解
	{
		cout << "error";
	}
	system("pause");
}

运行结果
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值