用计算机程序回溯法计算数独,编程之美1.15节:构造数独算法-回溯法和置换法...

1. 回溯法-程序

/**回溯法

* 生成数独矩阵

* From 编程之美1.15

*/

#include

#include

/*要生成的数独矩阵个数*/

#define SUDOKU_NUM 1

/**

* 函数is_digital_match

* 检测sudoku[i][j]上的值是否符合要求

*/

int is_digital_match(int sudoku[][9], int i, int j)

{

int temp = sudoku[i][j];

int p, q;

int m, n;

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

if(p!=i && sudoku[p][j]==temp)

return 0;

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

if(p!=j && sudoku[i][p]==temp)

return 0;

p = i/3;

q = j/3;

for(m=p*3; m

for(n=q*3; n

if(m!=i && n!=j && sudoku[m][n]==temp)

return 0;

return 1;

}

/*输出数独矩阵*/

void sudoku_print(int sudoku[][9])

{

int i,j;

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

{

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

printf("%4d", sudoku[i][j]);

printf("\n");

}

}

int main(void)

{

int sudoku[9][9] = {0};

int i, j, temp=0;

int k=0, num=0;

srand(time(0));

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

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

sudoku[i][j] = 0;

/*通过添加一些随机性,来每次生成不同的数独矩阵*/

/*添加更多随机性,则生成的矩阵将更随即*/

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

{

temp = rand() % 81;

sudoku[temp/9][temp%9] = i+1;

}

/*回溯法,构造数独矩阵*/

while(1)

{

i = k/9;

j = k%9;

while(1)

{

sudoku[i][j]++;

if(sudoku[i][j] == 10)

{

sudoku[i][j] = 0;

--k;

break;

}

else if(is_digital_match(sudoku, i, j) == 1)

{

++k;

break;

}

}

if(k == 81)

{

printf("Proper sudoku matrix %d: \n", ++num);

sudoku_print(sudoku);

if(num >= SUDOKU_NUM)

return 0;

--k;

}

}

return 0;

}

输出结果:

Proper sudoku matrix 1:

2 1 4 5 6 7 9 3 8

3 5 7 1 8 9 2 4 6

6 8 9 4 2 3 1 5 7

4 2 1 3 7 5 8 6 9

8 6 3 2 9 1 4 7 5

7 9 5 6 4 8 3 1 2

5 3 6 8 1 2 7 9 4

1 7 8 9 5 4 6 2 3

9 4 2 7 3 6 5 8 1

2. 置换的方法

/**简单方法

* 快速的构造数独矩阵的算法

* From:编程之美1.15节

* 通过置换,来生成矩阵

*/

#include

#include

int main()

{

int ini_matrix[3][3]; /*最初的3*3的小格子,用于生成9*9的大格子*/

int sudoku[9][9] = {0};

int i,j;

for(i=0; i<3; i++)

{

for (j=0; j<3; j++)

{

ini_matrix[i][j] = i*3+j+1;

}

}

/*设置随机数种子*/

srand(time(0));

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

{

int temp = rand() % 9;

j = ini_matrix[i/3][i%3];

ini_matrix[i/3][i%3] = ini_matrix[temp/3][temp%3];

ini_matrix[temp/3][temp%3] = j;

}

printf("Initial matrix:\n");

for(i=0; i<3; i++)

{

for (j=0; j<3; j++)

{

printf("%d\t", ini_matrix[i][j]);

}

printf("\n");

}

/*Put the ini_matrix to the center of sudoku*/

for(i=0; i<3; i++)

{

for (j=0; j<3; j++)

{

sudoku[i+3][j+3] = ini_matrix[i][j];

if(i==0)

{

sudoku[i+4][j] = ini_matrix[i][j];

sudoku[i+5][j+6] = ini_matrix[i][j];

}

else if(i==1)

{

sudoku[i+4][j] = ini_matrix[i][j];

sudoku[i+2][j+6] = ini_matrix[i][j];

}

else

{

sudoku[i+1][j] = ini_matrix[i][j];

sudoku[i+2][j+6] = ini_matrix[i][j];

}

if(j==0)

{

sudoku[i][j+4] = ini_matrix[i][j];

sudoku[i+6][j+5] = ini_matrix[i][j];

}

else if(j==1)

{

sudoku[i][j+4] = ini_matrix[i][j];

sudoku[i+6][j+2] = ini_matrix[i][j];

}

else

{

sudoku[i][j+1] = ini_matrix[i][j];

sudoku[i+6][j+2] = ini_matrix[i][j];

}

}

}

for(i=3; i<6; i++)

{

for (j=0; j<3; j++)

{

if(j==0)

{

sudoku[i-3][j+1] = sudoku[i][j];

sudoku[i+3][j+2] = sudoku[i][j];

}

else if(j==1)

{

sudoku[i-3][j+1] = sudoku[i][j];

sudoku[i+3][j-1] = sudoku[i][j];

}

else

{

sudoku[i-3][j-2] = sudoku[i][j];

sudoku[i+3][j-1] = sudoku[i][j];

}

}

}

for(i=3; i<6; i++)

{

for (j=6; j<9; j++)

{

if(j==6)

{

sudoku[i-3][j+1] = sudoku[i][j];

sudoku[i+3][j+2] = sudoku[i][j];

}

else if(j==7)

{

sudoku[i-3][j+1] = sudoku[i][j];

sudoku[i+3][j-1] = sudoku[i][j];

}

else

{

sudoku[i-3][j-2] = sudoku[i][j];

sudoku[i+3][j-1] = sudoku[i][j];

}

}

}

printf("Final matrix:\n");

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

{

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

{

printf("%d\t", sudoku[i][j]);

}

printf("\n");

}

return 0;

}

输出结果:

Initial matrix:

357

264

891

Final matrix:

189735426

735426189

426189735

891357264

357264891

264891357

918573642

573642918

642918573

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值