HDU1426 Sudoku Killer(DFS)

这道题我用了3天时间才A掉,感觉都对,和网上看到的也差不多,但交上去后不是超时,就是错误。总结一下,可能是思维比较混乱。
方法主要是先找出需要填写的位置,然后从头遍历这些位置,每个位置那1~9去试,不行就返回上一步(dfs)
注意,题目的输入方式比较坑,建议用cin。另外,题目要求两组解之间要有空格,只要有空格就好,至于中间的输入放在空格上还是下都无所谓(试过,好像可以)
下面是代码,边看边说
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int map[10][10];//用来存放数独的数组
int num;//记录需要填的格子数
struct node//记录需要填的格子位置
{
int x;
int y;
}a[
100];
bool judge(int k,int pos)//判断是否可填k为该点尝试放的值,pos为该点的位置(与结构体连用)
{
int x,y;
int i,j;
for(i=0;i<9;i++)
{
if(map[a[pos].x][i]==k || map[i][a[pos].y]==k){return 0;}//第一个判断同行的,第二个判断同列的
}
x=(a[pos].x/
3)*3;//各位同学可以自己带值试一下,用于找该点所在的九宫格的
y=(a[pos].y/
3)*3;
for(i=x;i<x+3;i++)//判断九宫格中是否能放入改值
{
for(j=y;j<y+3;j++)
{
if(map[i][j]==k)
{
return 0;
}
}
}
return 1;
}
void dfs(int pos)
{
if(pos==num)//所有的都填完了,输出
{
int i,j;
for(i=0;i<9;i++)
{
printf("%d",map[i][0]);
for(j=1;j<9;j++)
{
printf(" %d",map[i][j]);
}
printf("\n");
}
return;
}
int i;
for(i=1;i<=9;i++)//尝试1~9的值
{
if(judge(i,pos))//判断
{
map[a[pos].x][a[pos].y]=i;
dfs(pos+
1);
map[a[pos].x][a[pos].y]=0;//一次搜索结束后,还原该值,用于如果第一次暴力失败从另一个值再来。(加上较好)
}
}
return;
}
int main()
{
int q=0;//两组输出解之间的空格用
char c;//输入用,因为输入的有‘?’不能直接拿int来存
while(cin >> c)
{
num=
0;//初始置零
if(c=='?')
{
a[num].x=
0;
a[num].y=
0;
num++;
map[0][0]=0;
}
else{map[0][0]=c-'0';}//把数字放到map
int i,j;
for(i=0;i<9;i++)
{
for(j=0;j<9;j++)
{
if(i==0 && j==0){continue;}
cin >> c;
if(c=='?')
{
a[num].x=i;
a[num].y=j;
num++;
map[i][j]=0;
}
else{map[i][j]=c-'0';}
}
}
if(q++){printf("\n");}两组输出解之间的空格
dfs(
0);遍历
}
return 0;
}
总结:对于搞了半天都没搞出来的题目,如果找不到自己写的和答案有什么区别,最好还是直接放弃自己目前写的代码,去学别人的,可能效率比较高。


猜你喜欢

转载自blog.csdn.net/qq_30684235/article/details/79757984