HDU 1426 Sudoku Killer 枚举每一个空,深搜
2016-03-23 11:47
337 查看
题意:填数独,横竖1-9不重复,3*3方格1-9不重复(划分好的方格,看图)
想法:开始想着一行一行枚举,然后每行里面的空格再枚举,就是深搜套深搜,后来发现没必要,把空格按照顺序记录下来,往空格里面填数字,每填一个数字就判断一下,是否有不符合条件的,我们可以吧空格改成统一的一个数字,比如0或者是大于9的数字,这样如果有的空格还没有填写,在判断的时候也会返回false。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int map[10][10],cnt;
struct node
{
int x,y;
}point[100];
int flag;
bool judge(int num,int k)
{
for(int i=0;i<9;i++)
{
if(i!=point[num].y&&map[point[num].x][i]==k) return false;
if(i!=point[num].x&&map[i][point[num].y]==k) return false;
}
int x=point[num].x/3*3;
int y=point[num].y/3*3;
for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)
{
int rx=x+i;
int ry=y+j;
if((rx!=point[num].x||ry!=point[num].y)&&map[rx][ry]==k) return false;
}
}
return true;
}
void dfs(int num)
{
if(num==cnt)
{
flag=1;
return;
}
for(int i=1;i<10;i++)
{
if(judge(num,i))
{
map[point[num].x][point[num].y]=i;
dfs(num+1);
if(flag)
{
return;
}
map[point[num].x][point[num].y]=0;
}
}
return;
}
int main()
{
char g[3];
int t=0;
while(~scanf("%s",g))
{
cnt=0;
if(g[0]=='?')
{
point[cnt].x=0;
point[cnt++].y=0;
}
else map[0][0]=g[0]-'0';
for(int i=0;i<9;i++)
{
for(int j=0;j<9;j++)
{
if(i==0&&j==0) continue;
scanf("%s",g);
if(g[0]=='?')
{
point[cnt].x=i;
point[cnt++].y=j;
map[i][j]=0;
}
else
{
map[i][j]=g[0]-'0';
}
}
}
flag=0;
dfs(0);
if(t>0) cout<<endl;
t++;
for(int i=0;i<9;i++)
{
for(int j=0;j<9;j++)
{
if(j!=0) cout<<" ";
cout<<map[i][j];
}
cout<<endl;
}
}
return 0;
}
想法:开始想着一行一行枚举,然后每行里面的空格再枚举,就是深搜套深搜,后来发现没必要,把空格按照顺序记录下来,往空格里面填数字,每填一个数字就判断一下,是否有不符合条件的,我们可以吧空格改成统一的一个数字,比如0或者是大于9的数字,这样如果有的空格还没有填写,在判断的时候也会返回false。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int map[10][10],cnt;
struct node
{
int x,y;
}point[100];
int flag;
bool judge(int num,int k)
{
for(int i=0;i<9;i++)
{
if(i!=point[num].y&&map[point[num].x][i]==k) return false;
if(i!=point[num].x&&map[i][point[num].y]==k) return false;
}
int x=point[num].x/3*3;
int y=point[num].y/3*3;
for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)
{
int rx=x+i;
int ry=y+j;
if((rx!=point[num].x||ry!=point[num].y)&&map[rx][ry]==k) return false;
}
}
return true;
}
void dfs(int num)
{
if(num==cnt)
{
flag=1;
return;
}
for(int i=1;i<10;i++)
{
if(judge(num,i))
{
map[point[num].x][point[num].y]=i;
dfs(num+1);
if(flag)
{
return;
}
map[point[num].x][point[num].y]=0;
}
}
return;
}
int main()
{
char g[3];
int t=0;
while(~scanf("%s",g))
{
cnt=0;
if(g[0]=='?')
{
point[cnt].x=0;
point[cnt++].y=0;
}
else map[0][0]=g[0]-'0';
for(int i=0;i<9;i++)
{
for(int j=0;j<9;j++)
{
if(i==0&&j==0) continue;
scanf("%s",g);
if(g[0]=='?')
{
point[cnt].x=i;
point[cnt++].y=j;
map[i][j]=0;
}
else
{
map[i][j]=g[0]-'0';
}
}
}
flag=0;
dfs(0);
if(t>0) cout<<endl;
t++;
for(int i=0;i<9;i++)
{
for(int j=0;j<9;j++)
{
if(j!=0) cout<<" ";
cout<<map[i][j];
}
cout<<endl;
}
}
return 0;
}
相关文章推荐
- 使用GeneratorConfig自动生成Java类和XML文件
- Android开发实用工具汇总-持续更新
- Struts初始--环境搭建
- 求adc+de=ad+cde类似于这样问题
- 文章标题
- 团队问题
- 168.View the Exhibit and examine the description of SALES and PROMOTIONS tables.
- java多线程回顾3:线程安全
- 使用 AForge.NET 做视频采集
- Ubuntu中root用户和user用户的相互切换
- CString 到 float 的转换 小方法
- c++运算符重载
- iOS关于数组的那些小菜菜
- Css3之高级-1 Css复杂选择器(兄弟选择器 、属性选择器、伪类选择器、伪元素选择器)
- 生产者和消费者关系通过多线程来实现
- 转换时间为字符串
- 解决ora-02429:无法用于删除强制唯一/主键的索引
- Android三级目录、ListView单选/GridView单选、ListView多选/GridView多选
- KVO,NSNotification、Block、Delegate和KVO的区别
- 夜神安卓模拟器--虚拟神器