9*9数独问题——深度搜索算法

本文介绍了一个使用深度优先搜索(DFS)算法解决数独问题的C++程序。通过递归地尝试每种可能的数字填充空格,并检查是否违反数独规则,最终找到解决方案。文章提供了完整的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转自:http://blog.youkuaiyun.com/qq_31558353/article/details/50615760

作者原来的程序有问题,会改变到已有的数值。我在原有的基础上加了book标记,修改后验证OK。

数独是经典的逻辑问题,也可以使用DFS算法求解,下面短短几十行代码,就解决了数独的问题。

计算机真是个好东西啊!

#include "pch.h"
#include<stdio.h>
using namespace std;

bool bSign = false;
int num[9][9] = {
	0,0,0,0,0,2,0,5,0,
	0,7,8,0,0,0,3,0,0,
	0,0,0,0,0,4,0,0,0,
	5,0,0,0,0,0,0,0,0,
	0,0,0,0,0,0,1,0,0,
	0,0,0,0,3,0,7,0,8,
	2,0,0,0,0,0,0,4,0,
	0,0,0,0,0,5,0,9,0,
	0,1,0,0,7,0,0,0,0
};
bool book[81] = { false };
/* 输出数独矩阵 */
void Output()
{
	printf("\r\n");
	for (int i = 0; i < 9; i++)
	{
		for (int j = 0; j < 9; j++)
		{
			printf("%d ", num[i][j]);
			if (j % 3 == 2)
			{
				printf("   ");
			}
		}
		printf("\r\n");
		if (i % 3 == 2)
		{
			printf("\r\n");
		}
	}
}

/* 判断key填入n时是否满足条件 */
bool Check(int n, int key)
{
	/* 判断n所在横列是否合法 */
	for (int i = 0; i < 9; i++)
	{
		/* j为n竖坐标 */
		int j = n / 9;
		if (num[j][i] == key)
			return false;
	}

	/* 判断n所在竖列是否合法 */
	for (int i = 0; i < 9; i++)
	{
		/* j为n横坐标 */
		int j = n % 9;
		if (num[i][j] == key)
			return false;
	}

	/* 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 (num[i][j] == key)
				return false;
		}
	}

	/* 全部合法,返回正确 */
	return true;
}
/* 深搜构造数独 */
void DFS(int n)
{
	/* 所有的都符合,退出递归 */
	if (n > 80)
	{
		bSign = true;
		return;
	}
	/* 当前位不为空时跳过 */
	if (num[n / 9][n % 9] != 0)
	{
		book[n] = true;
		DFS(n + 1);
	}
	/* 否则对当前位进行枚举测试 */
	for (int i = 1; i <= 9; i++)
	{
		/* 满足条件时填入数字 */
		if (Check(n, i) && !book[n])
		{
			num[n / 9][n % 9] = i;
			book[n] = true;
			/* 继续搜索 */
			DFS(n + 1);
			/* 返回时如果构造成功,则直接退出 */
			if (bSign)
				return;
			/* 如果构造不成功,还原当前位 */
			num[n / 9][n % 9] = 0;
			book[n] = false;
		}
	}
}
int main()
{
	DFS(0);
	Output();
	return 0;
}

输出如下:

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值