数独(一个十分有趣的dfs实现)
今天敲了道数独题,hdu1426,希望自己了解一下。
hdu 1426 戳这里
思路感觉不是很难,但是代码量有点大搞得有很多bug,调试了很久才ac。
具体思路:
- 先构图(感觉这个比较恶心,我是先输入一个字符 再输入 后面八个字符,最后输入后面八行)这样比较简单但是很蠢的输入方法比较适合我。
- 然后就是找‘?’的点并且用结构体去储存一下。
然后就是dfs,遍历1~9这些数字去判断每个‘?’点的行 列 和所在方框能不能选择该数字。
AC代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <sstream>
#include <string>
#include <algorithm>
#include <list>
#include <map>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <cstdlib>
#include<iomanip>
using namespace std;
int map1[11][11];
int sum,f=0;
struct node{
int a,b;
};
node p[1001];
int panduan(int x,int y,int k) /*判断行列方格有没有重复*/
{
for(int i=1;i<=9;i++)
{
if(map1[x][i]==k)
return 0;
if(map1[i][y]==k)
return 0;
}
int x1=(x-1)/3*3;
int y1=(y-1)/3*3;
for(int i=x1+1;i<=x1+3;i++)
for(int j=y1+1;j<=y1+3;j++)
if(map1[i][j]==k)
return 0;
return 1;
}
void dfs(int n)
{
if(f)
return ;
if(n==sum)
{ f=1;
for(int i=1;i<=9;i++)
{
for(int j=1;j<=9;j++)
if(j==9)
cout<<map1[i][j];
else
cout<<map1[i][j]<<" ";
cout<<endl;
}
return ;
}
else
{
for(int i=1;i<=9;i++)
{
if(panduan(p[n].a,p[n].b,i))
{
map1[p[n].a][p[n].b]=i;
dfs(n+1);
}
}
if(f)
return ;
}
map1[p[n].a][p[n].b]=-1;
return ;
}
int main()
{ char num;
int t=0;
while(cin>>num)
{ if(num=='?')
map1[1][1]=-1;
else
map1[1][1]=num-48;
for(int i=2;i<=9;i++)
{ cin>>num;
if(num=='?')
map1[1][i]=-1;
else
map1[1][i]=num-48;
}
for(int i=2;i<=9;i++)
for(int j=1;j<=9;j++)
{
cin>>num;
if(num=='?')
map1[i][j]=-1;
else
map1[i][j]=num-48;
}
sum=0;
for(int i=1;i<=9;i++)
for(int j=1;j<=9;j++)
if(map1[i][j]==-1)
{
p[sum].a=i;
p[sum].b=j;
sum++;
}
if(f)
cout<<endl;
f=0;
dfs(0);
}
}