算法-洛谷-P1784 数独

该博客介绍了一种利用深度优先搜索(DFS)和回溯策略来解决数独问题的方法。代码示例展示了如何从输入的不完整数独盘面开始,递归填充数字并检查是否符合数独规则,直到找到唯一解。此算法适用于解决所有合格的数独题目。

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

题目描述
数独是根据 9×9 盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行、每一列、每一个粗线宫内的数字均含1−9,不重复。每一道合格的数独谜题都有且仅有唯一答案,推理方法也以此为基础,任何无解或多解的题目都是不合格的。输入一个未填的数独,要求输出填好的数独。

题目来源于洛谷网,网址https://www.luogu.com.cn/problem/P1784。

此题可以看作是深度优先搜索题目,同时用到回溯的思想,大体思路是从第一个空格开始,不断递归搜索,一直搜索到最后一个空格即可。

代码如下:

#include <stdio.h>
#include <stdlib.h>

int board[9][9];
int flag;

void input();
void dfs(int k);
int isempty(int k);
int canplace(int k, int num);
void place(int k, int num);
void output();

int main()
{
	input();
	dfs(1);
	
}

void input()
{
	for (int i = 0; i < 9; i++)
	{
		for (int j = 0; j < 9; j++)
		{
			scanf("%d", &board[i][j]);
		}
	}
}

void dfs(int k)
{
	if (flag)
	{
		return;
	}
	if (k == 82)
	{
		flag = 1;
		output();
		return;
	}
	if (!isempty(k))
	{
		dfs(k + 1);
		return;
	}
	for (int i = 1; i <= 9; i++)
	{
		if (canplace(k, i))
		{
			place(k, i);
			dfs(k + 1);
			place(k, 0);//回溯,这一步非常重要
		}
	}
	
}

int canplace(int k, int num)
{
	int row = (k - 1) / 9;
	int col = (k - 1) % 9;
	//判断所在行和列是否有相同元素
	for (int i = 0; i < 9; i++)
	{
		if (i != row && board[i][col] == num || i != col && board[row][i] == num)
		{
			return 0;
		}
	}
	//判断所在九宫格是否有相同元素
	for (int i = row / 3 * 3; i < row / 3 * 3 + 3; i++)
	{
		for (int j = col / 3 * 3; j < col / 3 * 3 + 3; j++)
		{
			if ((i != row || j != col) && board[i][j] == num)
			{
				return 0;
			}
		}
	}
	return 1;
}

void place(int k, int num)
{
	int row = (k - 1) / 9;
	int col = (k - 1) % 9;
	board[row][col] = num;
}

void output()
{
	for (int i = 0; i < 9; i++)
	{
		for (int j = 0; j < 9; j++)
		{
			printf("%d ", board[i][j]);
		}
		printf("\n");
	}
}

int isempty(int k)
{
	int row = (k - 1) / 9;
	int col = (k - 1) % 9;
	if (board[row][col] == 0)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}

需要注意深搜后要进行回溯。

以上就是我的实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值