数独问题--解题思路描述:

解题思路描述:

数独游戏,对于我们并不陌生,在意林和读者期刊的尾页不时会有刊登,所以规则是了解的:9*9网格,同时分成9个九宫格,有固定数字,而我们的任务是将剩余无数字部分填满,达到每一行,每一列,每一个九宫格都没有相同数字的要求。

首先第一个任务是生成数独终局:解决的方法有两种。

第一种方法:在排列之中,会发现有一种典型的矩阵组合刚好满足数独规则的要求:

1

2

3

4

5

6

7

8

9

7

8

9

1

2

3

4

5

6

4

5

6

7

8

9

1

2

3

9

1

2

3

4

5

6

7

8

6

7

8

9

1

2

3

4

5

3

4

5

6

7

8

9

1

2

8

9

1

2

3

4

5

6

7

5

6

7

8

9

1

2

3

4

2

3

4

5

6

7

8

9

1

 

 

 

 

这个数独由第一行的1~9的全排列决定,也就是说,全排列有多少种,这种典型数独就有多少种,而由9= 362880。因为第一个数字的要求,这种典型数独也就只能带来8= 40320的数独终局,离项目的1000000个数独终局还差将近25倍。

而在观察中得到,交换4~6行和7~9行中的任意两行,都可以得到一个新的符合要求的数独终局,这样子我们就可以在原来的基础上得到6*6=36倍的数独终局,符合了项目中的要求。具体代码实现如下:

 

void makesudo(int list[9]){

int lists[9];

char lis[600];

int bi = 0;

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

for (int j = 0; j < mov[i]; j++){

lists[mov[i] - 1 - j] = list[8 - j];

}

for (int j = 0; j < 9 - mov[i]; j++){

lists[j + mov[i]] = list[j];

}

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

if (j == 0) lis[bi++] = lists[j] + '0';

else{

lis[bi++] = ' ';

lis[bi++] = lists[j] + '0';

}

}

lis[bi++] = '\n';

}

lis[bi++] = '\n';

lis[bi] = '\0';

nown++;

fputs(lis, fp);

if (nown == n){

return;

}

}

 

void makemov(int list[9]){

mov[0] = 0;

for (int i = 0; i < 2; i++){

for (int j = 0; j < 6; j++){

for (int k = 0; k < 6; k++){

for (int a = 0; a < 2; a++){

mov[1+a] = er1[i][a];

}

for (int a = 0; a < 3; a++){

mov[3+a] = er2[chan[j][a]];

}

 

for (int a = 0; a < 3; a++){

mov[6+a] = er3[chan[k][a]];

}

 

makesudo(list);

 

if (nown == n){

goto part1;

}

}

}

}

part1:return;

}

 

第二种方法:

我们知道,当一个数独的条件数字少于30个时,可以有多个解,而当我们进行设计时可以通过解数独的形式直接生成数独终局,设计20个无关条件数字,运行接下来的求解函数即可。

求解函数会于下次更新给出。

 

posted @ 2018-04-12 22:14  Prisonerr  阅读(1656)  评论(0编辑  收藏  举报