题目描述
数独是根据 9×9 盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行、每一列、每一个粗线宫内的数字均含 1−9 ,不重复。每一道合格的数独谜题都有且仅有唯一答案,推理方法也以此为基础,任何无解或多解的题目都是不合格的。
芬兰一位数学家号称设计出全球最难的“数独游戏”,并刊登在报纸上,让大家去挑战。
这位数学家说,他相信只有“智慧最顶尖”的人才有可能破解这个“数独之谜”。
据介绍,目前数独游戏的难度的等级有一到五级,一是入门等级,五则比较难。不过这位数学家说,他所设计的数独游戏难度等级是十一,可以说是所以数独游戏中,难度最高的等级。他还表示,他目前还没遇到解不出来的数独游戏,因此他认为“最具挑战性”的数独游戏并没有出现。
输入格式
一个未填的数独。
输出格式
填好的数独。
输入输出样例
输入 #1
8 0 0 0 0 0 0 0 0
0 0 3 6 0 0 0 0 0
0 7 0 0 9 0 2 0 0
0 5 0 0 0 7 0 0 0
0 0 0 0 4 5 7 0 0
0 0 0 1 0 0 0 3 0
0 0 1 0 0 0 0 6 8
0 0 8 5 0 0 0 1 0
0 9 0 0 0 0 4 0 0
输出 #1
8 1 2 7 5 3 6 4 9
9 4 3 6 8 2 1 7 5
6 7 5 4 9 1 2 8 3
1 5 4 2 3 7 8 9 6
3 6 9 8 4 5 7 2 1
2 8 7 1 6 9 5 3 4
5 2 1 9 7 4 3 6 8
4 3 8 5 2 6 9 1 7
7 9 6 3 1 8 4 5 2
分析:
这道题要在你理解八皇后问题后才能做,它不同于八皇后问题只有0和1,数独输入0-9,输出1-9,简单说就是需要同时满足多种要求。
首先要先在main函数中写输入:
//这里记得定义一个全局变量a[10][10]
int main()
{
int i,j,k;
for(i=1;i<=9;i++)//一个简单的数组输入代码
{
for(j=1;j<=9;j++)
{
cin>>a[i][j];
}
}
sd(1,1);//使用数独函数
return 0;
}
然后看这张图:
根据这幅图,我们可以看出每一横排、每一竖排、每个小九宫格中都要有1-9这九个数字,所以我们需要在输入里添加三个数组去判断:
//m[10][10]、n[10][10]、f[10][10][10]都是全局定义
int main()
{
int i,j,k;
for(i=1;i<=9;i++)
{
for(j=1;j<=9;j++)
{
cin>>a[i][j];
k=a[i][j];//k为当前输入的数
m[i][k]=1;//标记当前行含有输入的数
n[j][k]=1;//标记当前列含有输入的数
f[(i+2)/3][(j+2)/3][k]=1;//标记当前九宫格含有输入的数(解析在下面)
}
}
sd(1,1);
return 0;
}
f数组判断方式的解析:
因为一共有九个九宫格,可以用(1,1)(1,2)(1,3)(2,1)(2,2)(2,3)(3,1)(3,2)(3,3)去表示,(用当前输入数的行数+2)去除3就可以表示它在哪一行的九宫格中,同理(用当前输入数的列数+2)去除3也可以表示它在哪一列的九宫格中,最后一个括号中的数标记输入的数在算出的九宫格中存在。
接着我们可以开始写推出数独的代码:
void sd(int x,int y)
{
int i;
if(x==9&&y==10) Pout();//如果判断到最后一行且判断完最后一列,输出数独
if(y==10) sd(x+1,1);如果判断到最后一列(当前非最后一行),判断下一行
if(a[x][y]!=0) sd(x,y+1);//如果当前数不为0(0相当于填数的地方)
else
{
for(i=1;i<=9;i++)
{
if(m[x][i]==0&&n[y][i]==0&&f[(x+2)/3][(y+2)/3][i]==0)//判断当前数是否能填入
{
a[x][y]=i;//把0替换为当前数
m[x][i]=1,n[y][i]=1,f[(x+2)/3][(y+2)/3][i]=1;//将相应的判断改为有
sd(x,y+1);//判断下一个数
a[x][y]=0;//清空当前数
m[x][i]=0,n[y][i]=0,f[(x+2)/3][(y+2)/3][i]=0;//清空标记
}
}
}
为了让代码更简单,这里创一个新函数Pout作为输出代码:
void Pout()
{
int i,j;
for(i=1;i<=9;i++)//输出
{
for(j=1;j<=9;j++)
{
cout<<a[i][j]<<" ";
}
cout<<endl;
}
exit(0);//结束
}
将他们组合起来,就能得到AC代码了!
AC代码:
#include<iostream>
using namespace std;
int a[10][10],m[10][10],n[10][10],f[10][10][10];
void Pout()
{
int i,j;
for(i=1;i<=9;i++)
{
for(j=1;j<=9;j++)
{
cout<<a[i][j]<<" ";
}
cout<<endl;
}
exit(0);
}
void sd(int x,int y)
{
int i;
if(x==9&&y==10) Pout();
if(y==10) sd(x+1,1);
if(a[x][y]!=0) sd(x,y+1);
else
{
for(i=1;i<=9;i++)
{
if(m[x][i]==0&&n[y][i]==0&&f[(x+2)/3][(y+2)/3][i]==0)
{
a[x][y]=i;
m[x][i]=1,n[y][i]=1,f[(x+2)/3][(y+2)/3][i]=1;
sd(x,y+1);
a[x][y]=0;
m[x][i]=0,n[y][i]=0,f[(x+2)/3][(y+2)/3][i]=0;
}
}
}
}
int main()
{
int i,j,k;
for(i=1;i<=9;i++)
{
for(j=1;j<=9;j++)
{
cin>>a[i][j];
k=a[i][j];
m[i][k]=1;
n[j][k]=1;
f[(i+2)/3][(j+2)/3][k]=1;
}
}
sd(1,1);
return 0;
}