【YBT高效进阶】1基础算法/4深度优先搜索/2数独游戏
内存限制:256 MiB
时间限制:1000 ms
标准输入输出
题目类型:传统
评测方式:文本比较
题目描述
数独是一种传统益智游戏,你需要把 9 ∗ 9 9*9 9∗9 的数独补充完整,使得图中每行、每列、每个 3 ∗ 3 3*3 3∗3 的九宫格内数字 1 − 9 1-9 1−9 均恰好出现一次。
请编写一个程序填写数独。
输入格式
输入包含多组测试用例。
每个测试用例占一行,包含 81 个字符,表达数独的 81 个格内数据(顺序总体由上到下,同行由左到右)。
每个字符都是一个数字或一个"." .(表示尚未填充)。
您可以假设输入中的每一个谜题都只有一个解决方案。
文件结尾处包含单词 end 的单行,表示输入结束。
输出格式
每个测试用例,输出一行数据,表示填充完全后的数独。
样例
样例输入
4.....8.5.3..........7......2.....6.....8.4......1.......6.3.7.5..2.....1.4......
......52..8.4......3...9...5.1...6..2..7........3.....6...1..........7.4.......3.
end
样例输出
417369825632158947958724316825437169791586432346912758289643571573291684164875293
416837529982465371735129468571298643293746185864351297647913852359682714128574936
思路
用3个数组保存每行列宫的数字使用情况
深度优先搜索
找到答案,标记,退出
代码
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
string str;
int h[9],l[9],g[9],x[82],y[82],z[82],w[82],num[513],s[513],tot,m[10]={
1,2,4,8,16,32,64,128,256,512};
bool d;
void DFS(int dep)
{
int bit,tem,mn=100000000,wz,i;
if(dep>tot)
{
cout<<str<<endl;
d=1;
return;
}
for(i=1; i<=tot; i++)
if(str[w[i]]=='.'&&s[h[x[i]]&l[y[i]]&g[z[i]]]<=mn)
{
wz=i,mn=s[h[x[i]]&l[y[i]]&g[z[i]]];
if(mn==0)return;
}
for(bit=h[x[wz]]&l[y[wz]]&g[z[wz]]; bit; bit-=tem)
{
tem=bit&-bit,h[x[wz]]^=tem,l[y[wz]]^=tem,g[z[wz]]^=tem,str[w[wz]]=num[tem]+'0';
DFS(dep+1);
if(d)return;
h[x[wz]]^=tem,l[y[wz]]^=tem,g[z[wz]]^=tem;
}
str[w[wz]]='.';
return;
}
int main()
{
int i,tem;
ios::sync_with_stdio(false);
memset(s,0,sizeof(s));
for(i=0; i<9; i++)num[m[i]]=i+1;
for(i=0; i<512; i++)
for (tem=i; tem; tem-=tem&-tem,s[i]++);
for(cin>>str; str!="end"; cin>>str)
{
for(i=0; i<9; i++)
h[i]=l[i]=g[i]=511;
for(tot=0,d=0,i=0; i<81; i++)
if(str[i]=='.') w[++tot]=i,x[tot]=i/9,y[tot]=i%9,z[tot]=x[tot]/3*3+y[tot]/3;
else h[i/9]^=m[str[i]-49],l[i%9]^=m[str[i]-49],g[i/27*3+(i%9)/3]^=m[str[i]-49];
DFS(1);
}
return 0;
}