/*
题目:
填充数独游戏
分析:
先从后面开始搜,也就是从第八十个开始搜
1、如果一个小的方格内已经包含了非零的数,则继续向下搜
2、如果一个小的方格内是一个零数,也就是还没有放入相应的数,则对其从零到九开始尝试
3、对每一个数的尝试,检查其合法性:在其所在的3*3方格内是否合适;在此行是否合适,在此列是否合适
4、如果经过以上条件可以的话那么这个数字就可以放在此小方格上,然后继续进行搜索。
*/
#include <iostream>
#include <cstring>
#include <string>
using namespace std;
int a[10][10];
int can(int i,int x,int y)
{ //i:尝试填下的数,x:行数,y:列数
for(int j=1;j<=9;j++) //计算同行或同列是否已有此数
if(a[x][j]==i||a[j][y]==i)
return 0;
int r = (x-1)/3; //计算同一方框内的行序号
int l = (y-1)/3; //计算同一方框内的列序号
for(int j=r*3+1;j<=r*3+3;j++)
for(int k=l*3+1;k<=l*3+3;k++)
if(a[j][k]==i)
return 0;
return 1;
}
int dfs(int n)
{ //n:剩下未填的数
if(n==0) //如果剩下为填的数为0,证明全部填好,返回1
return 1;
int x = (n+8)/9; //计算行号
int y = n%9; //计算列号
if(y==0) //如果列号为0,置9
y = 9;
if(a[x][y]) //已经给出数了
{
if(dfs(n-1)) //如果剩下的能够安置好,返回1,否则返回0
return 1;
}
else //如果没有给出
{
for(int i=1;i<=9;i++) //从1到9尝试填充
{
if(can(i,x,y)) //如果可以填下此数
{
a[x][y] = i; //标记此格
if(dfs(n-1)) //如果剩下的数能安置好,则返回1
return 1;
a[x][y] = 0; //剩下的数不能安置好,返回0且把此格标记空格0
}
}
}
return 0;
}
int main()
{
freopen("sum.in","r",stdin);
freopen("sum.out","w",stdout);
int n;
cin>>n;
while(n--)
{
memset(a,0,sizeof(a));
for(int i=1;i<=9;i++)
{
string s;
cin>>s;
for(int j=1;j<=9;j++)
a[i][j] = s[j-1]-'0';//字符转换数字
}
if(dfs(81))
{
for(int i=1;i<=9;i++)
{
for(int j=1;j<=9;j++)
cout<<a[i][j]; //输出数独
cout<<endl;
}
}
}
return 0;
}
编辑器加载中...