#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define M 12
#define N 10
/*
* 005300000
800000020
070010500
400005300
010070006
003200080
060500009
004000030
000009700
*/
int check(char table[][10],int x,int y,int k)
{
//检查同行同列
for(int i=0;i<9;i++) {
if (table[x][i] == (char) ('0' + k)) //不能重复 table[i]的行列
return 0;
if (table[i][y] == (char)('0' + k))
return 0;
}
//检查小九宫格3*3
// (x/3)*3是小九宫点的起点范围为0-3
for(int i=(x/3)*3;i<(x/3+1)*3;i++) //行的起点 x/3*3
{
for(int j=(y/3)*3;j<(y/3+1)*3;j++) //列
{
if(table[i][j]==(char)('0'+k)) //有与要放入的i相同的数返回false
return 0;
}
}
return 1;
}
//核心代码dfs
void dfs(char table[][10],int x,int y) {
if(x==9) //结束
{
for(int i=0;i<9;i++) //打印
printf("%2s \n",table[i]);
exit(0); //唯一解退出系统;
}
if (table[x][y] == '0') //有0的地方填入数字
{
//选1-9的合法数字填到x,y这个位置
for(int i=1;i<10;i++)
{
if(check(table,x,y,i))//在x这个行以及j这个列和小九宫格里面是否有i了
{
table[x][y]=(char)('0'+i);//是真,就可以填i这个位置,然后转移到下一个状态转为字符
dfs(table,x+(y+1)/9,(y+1)%9); //行要不要动取决于y有没有到最后一列,y上限8,y=8时x+1下一行,只有等于8,y之后归0
table[x][y]='0'; //平行状态 回溯
}
}
}
else
{
//继续找下一个需要处理的位置
dfs(table,x+(y+1)/9,(y+1)%9);
}
}
int main()
{
char table[10][10];
for(int i=0;i<9;i++)
scanf("%s",table[i]);
dfs(table,0,0);
}
解数独 回溯
最新推荐文章于 2024-08-19 11:12:00 发布