老师要我们做题,求dalao解释代码,如题:\
数独是一种传统益智游戏,你需要把一个9×9的数独补充完整,使得图中每行、每列、每个3×3的九宫格内数字1~9均恰好出现一次。
请编写一个程序填写数独。
输入格式 输入包含多组测试用例。
每个测试用例占一行,包含81个字符,代表数独的81个格内数据(顺序总体由上到下,同行由左到右)。
每个字符都是一个数字1~9或一个”.”(表示尚未填充)。
您可以假设输入中的每个谜题都只有一个解决方案。
文件结尾处为包含单词“end”的单行,表示输入结束。
输出格式
每个测试用例,输出一行数据,代表填充完全后的数独。
样例
输入样例
.2738..1..1...6735.......293.5692.8...........6.1745.364.......9518...7..8..6534.
......52..8.4......3...9...5.1...6..2..7........3.....6...1..........7.4.......3.
end
输出样例
527389416819426735436751829375692184194538267268174593643217958951843672782965341
416837529982465371735129468571298643293746185864351297647913852359682714128574936
代码
#include <bits/stdc++.h>
using namespace std;
string s;
int a[10][10],num[1000],hang[13],lie[13],gong[13];
void init()
{
for(int i=0;i<9;i++)
hang[i]=lie[i]=gong[i]=511;
}
int find(int i,int j)
{
return hang[i]&lie[j]&gong[i/3*3+j/3];
}
bool dfs()
{
int x=-1,y=-1,ans=10;
for(int i=0;i<9;i++)
for(int j=0;j<9;j++)
if(a[i][j]==0)
{
int p=find(i,j);
if(num[p]<ans)
ans = num[p],x=i,y=j;
}
if(ans==10)
return true;
int p=find(x,y);
for(int i=0;i<9;i++)
if(p&(1<<i))
{
int k=(1<<i);
hang[x]-=k;
lie[y]-=k;
gong[x/3*3+y/3]-=k;
a[x][y]=i+1;
if(dfs())
return true;
hang[x]+=k;
lie[y]+=k;
gong[x/3*3+y/3]+=k;
a[x][y]=0;
}
return false;
}
int main()
{
for(int i=1;i<512;i++)
{
int k=i;
while(k)
{
k-=(k&-k);
num[i]++;
}
}
while(cin>>s&& s!= "end")
{
init();
int l=0;
for(int i=0;i<9;i++)
for(int j=0;j<9;j++)
{
a[i][j]=(s[l]=='.')? 0 : s[l]-'0';
l++;
if(a[i][j]==0)
continue;
int p=1 << (a[i][j]-1);
hang[i]-=p;
lie[j]-=p;
gong[i/3*3+j/3]-=p;
}
dfs();
for(int i=0;i<9;i++)
for(int j=0;j<9;j++)
cout << a[i][j];
puts("");
}
return 0;
}