您的位置:首页 > 编程语言 > C语言/C++

数独游戏的简单回溯解法

2015-11-18 23:28 465 查看
今天哥们儿突然让我帮着解个数独,一开始以为只要循环遍历就可以了,后来想想有些太麻烦,想着自己以前写过八皇后问题,研究了一下,还真弄出来了,高兴!

#include <iostream>
#include <fstream>
int num[9][9];
int posX[81]= {0};
int posY[81]= {0};
int resCount=0;
using namespace std;
void print()
{
for(int i=0; i<9; i++)
{

for(int j=0; j<9; j++)
{
cout<<num[i][j]<<" ";
}
cout<<endl;
}
}
void recordPos() //记录还没有添加数字的位置
{
for(int i=0; i<9; i++)
{
for(int j=0; j<9; j++)
{
if(num[i][j]==0)
{
posX[resCount]=i;
posY[resCount]=j;
resCount++;
}
}
}
}
bool checkZone(int x,int y)//检测该数在自己3*3的方格是否合法
{
int tmpX = 3*(x/3);
int tmpY = 3*(y/3);
for(int i=tmpX; i<tmpX+3; ++i)
{
for(int j=tmpY; j<tmpY+3; ++j)
{
if(x==i&&j==y)continue;
if(num[x][y]==num[i][j])return false;
}
}
return true;
}
bool check(int step) //检测是否合法
{
int x=posX[step];
int y=posY[step];
for(int i=0; i<9; i++) //行重复
{
if(num[x][y]==num[x][i]&&y!=i)return false;
}
for(int i=0; i<9; i++) //列重复
{
if(num[x][y]==num[i][y]&&x!=i)return false;
}
if(!checkZone(x,y))return false;
return true;
}
void f(int step)
{
if(step==resCount)
{
print();
return ;
}
for(int i=1; i<=9; i++)
{
num[posX[step]][posY[step]]=i;
if(check(step))
{
f(step+1);
}
num[posX[step]][posY[step]]=0;
}
}
int main()
{
freopen("in.txt","r",stdin);
for(int i=0; i<9; i++)
{
for(int j=0; j<9; j++)
{
cin>>num[i][j];
}
}
recordPos();
f(0);
return 0;
}
测试用例:

2 0 6 0 0 1 0 8 0

1 7 0 0 0 9 0 6 0

0 0 0 4 6 7 0 0 0

6 1 0 0 4 0 8 0 0

0 0 2 0 0 0 3 0 0

0 0 5 0 0 0 0 9 6

0 0 0 2 1 5 0 0 0

0 3 0 6 9 4 0 2 8

0 2 0 7 0 0 6 0 5
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c++ 数独