您的位置:首页 > 其它

数独的求解算法 回溯

2013-02-11 22:15 751 查看
/*

数独的算法,有说用深度优先的,有说用dancing links(双向链表),这些技术不太熟,先用数组实现吧,

时间复杂度大了点,求解思路要优化下

0,9,0, 0,0,2, 0,0,1,

0,0,0, 0,6,0, 0,0,2,

0,0,0, 0,0,0, 4,0,0,

6,0,0, 0,8,0, 0,0,0,

0,2,0, 0,0,0, 0,0,0,

0,0,1, 7,0,4, 0,0,0,

3,6,0, 0,0,0, 0,0,0,

0,0,7, 0,0,0, 5,0,0,

9,5,0, 0,0,7, 0,0,8

*/

// sudokuadv.cpp : 定义控制台应用程序的入口点。

//

//二维数组的回溯

#include "stdafx.h"

#include <iostream>

using namespace std;

char str[9][10];

int jiaquanArr[10]={0,1,2,4,8,16,32,64,128,256};

int sudokuArr[9][9]={

0,9,0, 0,0,2, 0,0,1,//1 2 9

0,0,0, 0,6,0, 0,0,2,//2 6

0,0,0, 0,0,0, 4,0,0,//4

6,0,0, 0,8,0, 0,0,0,//6 8

0,2,0, 0,0,0, 0,0,0,//2

0,0,1, 7,0,4, 0,0,0,//1 4 7

3,6,0, 0,0,0, 0,0,0,//3 6

0,0,7, 0,0,0, 5,0,0,//5 7

9,5,0, 0,0,7, 0,0,8 //5 7 8 9

};

int sudokuright[9][9]=

{

4, 9, 5, 3, 7, 2, 6, 8, 1,

1, 7, 3, 4, 6, 8, 9, 5, 2,

2, 8, 6, 1, 9, 5, 4, 3, 7

};

/*

4 9 5 3 7 2 6 8 1

1 7 3 4 6 8 9 5 2

2 8 6 1 9 5 4 3 7

6 4 9 5 8 1 2 7 3

7 2 8 9 3 6 1 4 5

5 3 1 7 2 4 8 6 9

3 6 2 8 5 9 7 1 4

8 1 7 2 4 3 5 9 6

9 5 4 6 1 7 3 2 8

*/

bool bsudokuArr[9][9]={true};

//散列表,判断[1,9]取值能不能用,默认为true,用于辅助重复判断

bool bLiechongfuArr[9][10]={

{false,true,true,true,true,true,true,true,true,true},//第零列,

{false,true,true,true,true,true,true,true,true,true},//第一列

{false,true,true,true,true,true,true,true,true,true},

{false,true,true,true,true,true,true,true,true,true},

{false,true,true,true,true,true,true,true,true,true},

{false,true,true,true,true,true,true,true,true,true},

{false,true,true,true,true,true,true,true,true,true},

{false,true,true,true,true,true,true,true,true,true},

{false,true,true,true,true,true,true,true,true,true}//第八列

};

//散列表,判断[1,9]取值能不能用,默认为true,用于辅助重复判断

bool bHangchongfuArr[9][10]={

{false,true,true,true,true,true,true,true,true,true},//第零行,

{false,true,true,true,true,true,true,true,true,true},//第一行

{false,true,true,true,true,true,true,true,true,true},

{false,true,true,true,true,true,true,true,true,true},

{false,true,true,true,true,true,true,true,true,true},

{false,true,true,true,true,true,true,true,true,true},

{false,true,true,true,true,true,true,true,true,true},

{false,true,true,true,true,true,true,true,true,true},

{false,true,true,true,true,true,true,true,true,true}//第八行

};

bool IsPassCheckLineAndRow(int &line, int &row)

{

if(row<0 && line==0)

return false;

if(row < 0 && line>0)

{

row=8;

line--;

}

if(row > 8 && line<8)

{

row=0;

line++;

}

return true;

}

void ProductAllBsudokuArr(int sudokuArr[9][9], bool bsudokuArr[9][9])

{

int const MaxHang=9;

int const MaxLie=9;

int temp;

for(int i=0; i<MaxHang; i++)

{

for(int j=0; j<MaxLie; j++)

{

temp=sudokuArr[i][j];

if(temp != 0)

{

bsudokuArr[i][j]=false;

bHangchongfuArr[i][temp]=false;

bLiechongfuArr[j][temp]=false;

}

else

{

bsudokuArr[i][j]=true;

}

}

}

}

bool IsPassHangChongFu(int a[9][9], int line, int row, int shitanzhi)

{

if(bHangchongfuArr[line][shitanzhi])

return true;

else

return false;

}

bool IsPassLieChongFu(int a[9][9], int line, int row, int shitanzhi)

{

if(bLiechongfuArr[row][shitanzhi])

return true;

else

return false;

}

bool IsPassJiuGong(int a[9][9],int line,int row,int shitanzhi)

{

bool lab=true;

int i,j;

int sumzuo,sumzhong,sumyou;

sumzuo=sumzhong=sumyou=0;

for(i=line-2; i<line; i++)

{

sumzuo +=(jiaquanArr[ a[i][0] ]+jiaquanArr[ a[i][1] ]+jiaquanArr[ a[i][2] ]);

sumzhong+=(jiaquanArr[ a[i][3] ]+jiaquanArr[ a[i][4] ]+jiaquanArr[ a[i][5] ]);

sumyou +=(jiaquanArr[ a[i][6] ]+jiaquanArr[ a[i][7] ]+jiaquanArr[ a[i][8] ]);

}

sumzuo +=(jiaquanArr[ a[line][0] ]+jiaquanArr[ a[line][1] ]+jiaquanArr[ a[line][2] ]);

sumzhong+=(jiaquanArr[ a[line][3] ]+jiaquanArr[ a[line][4] ]+jiaquanArr[ a[line][5] ]);

sumyou +=(jiaquanArr[ a[line][6] ]+jiaquanArr[ a[line][7] ]+jiaquanArr[ shitanzhi ]);//这一个特殊点, a[line][8]还未有效

if( (511==sumzuo)

&&(511==sumzhong)

&&(511==sumyou)

)

return true;

else

return false;

}

void ProductSudokuJie()

{

int t;

int count=0;

int line, row, shitanzhi;

int a[9][9];

for(line=0; line<9; line++)

{

for(row=0; row<9; row++)

{

a[line][row]=sudokuArr[line][row];//预设固定值

}

}

a[0][0]=4;//4是a[0][0]第一个可用值

//更新bLiechongfuArr和bHangchongfuArr

bHangchongfuArr[0][ a[0][0] ]=false;

bLiechongfuArr[0][ a[0][0] ]=false;

line =0;

row =1;

shitanzhi=1;

while(true)

{

if(line == 1 && row==2)

t=0;

if(line == 0 && row<0)

break;

if(line == 8 && row>8)

{

//输出可能解或统计

count++;

row--;if(!IsPassCheckLineAndRow(line,row)) break;

while(bsudokuArr[line][row] == false)//sudoku数组中,该元素为固定值

{

row--;if(!IsPassCheckLineAndRow(line,row)) break;

}

if(!IsPassCheckLineAndRow(line,row)) break;

shitanzhi=a[line][row]+1;

//更新bLiechongfuArr和bHangchongfuArr

bHangchongfuArr[line][ a[line][row] ]=true;

bLiechongfuArr[row][ a[line][row] ]=true;

}

if(shitanzhi > 9)

{

row--;if(!IsPassCheckLineAndRow(line,row)) break;

while(bsudokuArr[line][row] == false)//sudoku数组中,该元素为固定值

{

row--;if(!IsPassCheckLineAndRow(line,row)) break;

}

if(!IsPassCheckLineAndRow(line,row)) break;

shitanzhi=a[line][row]+1;

//更新bLiechongfuArr和bHangchongfuArr

bHangchongfuArr[line][ a[line][row] ]=true;

bLiechongfuArr[row][ a[line][row] ]=true;

}

else

{

if(bsudokuArr[line][row] == false)//sudoku数组中,该元素为固定值

{

if( (line ==2 && row==8)

||(line ==5 && row==8)

||(line ==8 && row==8)

)

{

if(IsPassJiuGong(a, line, row, a[line][row]))//通过九宫检测

{

shitanzhi=1;

row++;IsPassCheckLineAndRow(line,row);

}

else

{

row--;if(!IsPassCheckLineAndRow(line,row)) break;

while(bsudokuArr[line][row] == false)//sudoku数组中,该元素为固定值

{

row--;if(!IsPassCheckLineAndRow(line,row)) break;

}

if(!IsPassCheckLineAndRow(line,row)) break;

shitanzhi=a[line][row]+1;

//更新bLiechongfuArr和bHangchongfuArr

bHangchongfuArr[line][ a[line][row] ]=true;

bLiechongfuArr[row][ a[line][row] ]=true;

}

}

else

{

shitanzhi=1;

row++;IsPassCheckLineAndRow(line,row);

}

}

else

{

if(IsPassHangChongFu(a, line, row, shitanzhi) && IsPassLieChongFu(a, line, row, shitanzhi))

{

if( (line ==2 && row==8)

||(line ==5 && row==8)

||(line ==8 && row==8)

)

{

if(IsPassJiuGong(a, line, row, shitanzhi))//九宫判定

{

a[line][row]=shitanzhi;

//更新bLiechongfuArr和bHangchongfuArr

bHangchongfuArr[line][ a[line][row] ]=false;

bLiechongfuArr[row][ a[line][row] ]=false;

shitanzhi=1;

row++;IsPassCheckLineAndRow(line,row);

}

else

{

shitanzhi++;

}

}

else

{

a[line][row]=shitanzhi;

//更新bLiechongfuArr和bHangchongfuArr

bHangchongfuArr[line][ a[line][row] ]=false;

bLiechongfuArr[row][ a[line][row] ]=false;

shitanzhi=1;

row++;IsPassCheckLineAndRow(line,row);

}

}

else

{

shitanzhi++;

}

}

}

}

cout<<count<<endl;

}

int _tmain(int argc, _TCHAR* argv[])

{

ProductAllBsudokuArr(sudokuArr, bsudokuArr);

ProductSudokuJie();

getchar();

return 0;

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