您的位置:首页 > 其它

回溯法----- 解数独游戏(1)

2013-11-26 09:42 225 查看
数独游戏的规则:

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: