题目描述
数独是根据 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;
}
}
需要注意深搜后要进行回溯。
以上就是我的实现。