数独简介:
数独 是一种逻辑性的数字填充游戏,玩家须以数字填进每一格,而每行、每列和每个宫(即3x3的大格)有齐1至9所有数字。游戏设计者会提供一部份的数字,使谜题只有一个答案。一个已解答的数独其实是一种多了宫的限制的拉丁方阵,因为同一个数字不可能在同一行、列或宫中出现多于一次。
深度优先遍历算法:
学过数据结构的同学都知道,深度遍历算法最开始是为解决树的遍历发展出来的,而后用于图的遍历。就像走迷宫似的,走到一个点之后发现不能满足当前条件,于是必须得退回到前一个状态继续探索迷宫。主要思想过程我就不用再说了,本科期间大家已经很熟了。
算法过程分析:
先假设已经生成了一个数独谜题,例如上题中的数独谜题,先填第一行第二列中的空格,首先遍历横排,再遍历竖排,最后遍历方格。如此循环,如果碰到数字相同的情况,则需要换另外一个数字,如果1到9的全部数字情况都不满足的情况下,则需要返回到前一个状态,如果前一个状态还不满足,则继续返回知道满足在继续遍历。
算法代码:
#include <iostream>
using namespace std;
char map[10][10];
struct
{
int h;
int l;
}cor[90];
int count;
bool fit(char number,int x,int y)//判断是否符合填入条件
{
int i,j;
for(i=0;i<9;i++)
if(map[x][i]==number||map[i][y]==number)
return false;
int kh=x-x%3;
int kl=y-y%3;
for(i=kh;i<kh+3;i++)
for(j=kl;j<kl+3;j++)
if(map[i][j]==number)
return false;
return true;
}
void search(int x)
{
int i,j;
if(x>count)//遍历成功则打印
{
for(i=0;i<9;i++)
{
for(j=0;j<8;j++)
cout<<map[i][j]<<" ";
cout<<map[i][8]<<endl;
}
return ;
}
for(i=1;i<=9;i++)
{
char number=i+'0';
if(fit(number,cor[x].h,cor[x].l))
{
map[cor[x].h][cor[x].l]=number;
search(x+1);//遍历下一个?处的数字
map[cor[x].h][cor[x].l]='?';//需要改变到前一个状态
}
}
}
int main()
{
int i,j;
while(true)
{
count=-1;
for(i=0;i<9;i++)
for(j=0;j<9;j++){
cin>>map[i][j];//用?号代替没有填入数字的空格
if(map[i][j]=='?')
{
++count;//记录空格的数量
cor[count].h=i;//记录空格的行
cor[count].l=j;//记录空格的列
}
}
search(0);//开始遍历
cout<<endl;
}
return 0;
}
测试事例:
谜题就用上图出现过的数字
测试后:
测试成功!!!!