数独游戏的规则:
1 每个数字在每一行只能出现一次
2 每个数字在每一列只能出现一次
3 每个数字在每一区只能出现一次
下面的input.txt是一个例子的约束条件 第一列表示每一个数所在的行 第二列表示每一个数所在的列,第三个这个位置上的值。
Input.txt
1 1 7
1 4 1
1 8 8
1 9 3
2 1 4
2 3 2
2 5 7
2 6 3
3 4 4
3 5 5
3 8 2
3 9 7
4 3 7
4 7 3
4 8 1
4 9 2
5 2 4
5 3 3
5 4 8
6 3 5
6 5 9
7 2 2
7 3 1
7 5 8
8 2 3
8 4 2
8 6 1
8 7 8
9 7 2
9 8 6
9 9 1
一 回溯法
//============================================
#include
#include
using namespace std;
int State[9][9];
///------------------------------
void InitState()
{
for (int i=0; i<9; i++)
{
for (int j=0; j<9;j++)
{
State[i][j] = 0;
}
}
}
//-------------------------------
void Load()
{
freopen("input.txt","r",stdin); //输入从input.txt
int x, y, value;
int temp = 0;
while (scanf ("%d %d %d", &x, &y, &value) != EOF)
{
State[x-1][y-1] = value;
}
}
//---------------------------------
//检查每一个小区内只能出现一次
bool ChechZone(int x, int y, int i)
{
int xZone = 3 * (x / 3); //找到每个小区的位置
int yZone = 3 * (y / 3);
int j = 0;
int k = 0;
bool flag = true;
for (j=xZone; j
{
for (k=yZone; k
{
//if (x == j && y == k)
//{
// continue;
//}
if ((x != j || y != k) && State[j][k] == i)
{
flag = false;
goto A1;
}
}
}
A1:
return flag;
}
//--------------------------------
//检查是否符合条件
bool ChechAssign(int x, int y, int i)
{
bool flag = true;
for (int k=0; k<9; k++)
{
if (k != y && i == State[x][k] )
{
flag = false;
}
if (k != x && i == State[k][y] )
{
flag = false;
}
if (!ChechZone(x, y, i))
{
flag = false;
}
}
return flag;
}
///------------------------------
int Search (int depth)
{
if (depth >= 81)
{
//return Chech();
return 1;
}
int x, y;
x = depth / 9 ;
y = depth % 9 ;
//检查x y有没有被 赋值
if (0 != State[x][y])
{
return Search (depth + 1);
}
else //尝试赋值
{
for (int i=1; i<=9; i++)
{
//检查是否违反约束条件
State[x][y] = i;
if (ChechAssign(x, y, i))
{
if (Search(depth + 1))
{
return 1;
}
}
State[x][y] = 0;
}
return 0;
}
}
///---------------------------------------
void OutputState()
{
for (int i=0; i<9; i++)
{
for (int j=0; j<9; j++)
{
cout << State[i][j] << " ";
if (0 == (j+1) % 3)
{
cout << " ";
}
}
if (0 == (i + 1) % 3)
{
cout << endl;
}
cout << endl;
}
cout << endl;
}
//-------------------------------------
int main ()
{
cout << "=======初始化========"<< endl << endl;
InitState();
//输入函数
Load();
OutputState();
cout << "=======结果为======="<< endl << endl;
//搜索
if (Search(0))
{
OutputState();
}
else
{
//输出提示信息
cout << "搜索失败!!!"<< endl;
}
cout << "===================="<< endl << endl;
return 0;
}
二 优化后的回溯
就是先排序后再回溯 排序的依据是:先算出第一个空格的所在行各所在列对他的约束的个数。然后从大到小进行排序。
优化后的程序如下:
#include
#include
using namespace std;
// -------------------------------------------------------------------------
int State[9][9];
int StateSort[81][3]; //记录每个空元素的所在行列已有的数字个数 非空元素为0