求用C语言编一个解九宫格数独的程序

求用C语言编一个解九宫格数独的程序,第1张

前两天刚写完,还没优化,已运行通过了.

晕,一维的好麻烦,这个也是碰巧前两天刚写好的,你看着自己修改下

#include <stdio.h>

typedef struct

{

int line

int row

int num

}Node

int main()

{

/*

int a[9][9]={

{4,0,3,6,0,0,0,0,0},

{0,0,0,0,0,1,0,2,4},

{0,1,0,0,4,0,5,0,0},

{0,0,0,9,0,4,0,6,0},

{3,0,2,0,0,0,4,0,9},

{0,7,4,1,0,3,0,0,0},

{0,0,1,0,9,0,0,4,0},

{2,4,0,3,0,0,0,0,0},

{0,0,0,4,0,8,2,0,7}}

*/

int a[9][9]={

{0,0,0,8,0,0,0,6,0},

{8,7,0,0,0,0,0,0,0},

{2,9,0,0,4,1,0,0,5},

{0,0,5,7,0,0,0,0,9},

{0,2,0,0,0,0,0,1,0},

{9,0,0,0,0,4,3,0,0},

{7,0,0,6,1,0,0,9,8},

{0,0,0,0,0,0,0,5,2},

{0,6,0,0,0,9,0,0,0}}

/*

int a[9][9]={

{0,2,0,0,6,0,0,0,0},

{0,9,0,4,0,5,1,3,0},

{0,0,8,7,0,0,0,0,5},

{6,0,0,3,0,0,4,0,0},

{0,0,0,9,0,6,0,0,0},

{0,0,7,0,0,1,0,0,3},

{4,0,0,0,0,7,3,0,0},

{0,8,5,2,0,4,0,7,0},

{0,0,0,0,9,0,0,1,0}}

*/

/*

int a[9][9]={

{0,0,3,0,2,0,0,0,6},

{0,0,2,0,9,0,0,0,4},

{7,0,0,8,0,0,2,0,3},

{0,8,0,0,7,0,5,0,0},

{0,7,0,1,0,6,0,3,0},

{0,0,0,2,0,0,0,9,0},

{4,0,6,0,0,8,0,0,5},

{6,0,0,0,4,0,3,0,0},

{9,0,0,0,1,0,7,0,0}}

*/

int i,j,n,en,flag,y,k=0,x,qu,p,q

Node b[70]

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

{

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

{

if(!a[i][j])

{

b[k].line=i

b[k].row=j

b[k].num=0

k+=1

}

}

}

en=k

/*从b[0]开始试,若b[k].num>9,则k-1,否则k+1*/

for(k=0k<en)

{

++b[k].num

i=b[k].line

j=b[k].row

a[i][j]=b[k].num

n=0

while(n<9&&b[k].num<=9)

{

if(n==i)

{

for(y=0y<9y++)

{

if(y==j)

continue

if(a[n][y]==a[i][j])

flag=1

}

}

else if(n==j)

{

for(y=0y<9y++)

{

if(y==i)

continue

if(a[y][n]==a[i][j])

flag=1

}

}

/*判断同一块中有没有相同值*/

qu=3*(i/3)+j/3

switch(qu)

{

case 0:x=0

y=0

break

case 1:x=0

y=3

break

case 2:x=0

y=6

break

case 3:x=3

y=0

break

case 4:x=3

y=3

break

case 5:x=3

y=6

break

case 6:x=6

y=0

break

case 7:x=6

y=3

break

default :x=6

y=6

break

}

p=x

q=y

for(x<p+3x++)

{

for(y<q+3y++)

{

if(x==i&&y==j)

continue

if(a[x][y]==a[i][j])

{

flag=1

break

}

}

if(flag==1)

break

}

if(flag==1)

{

a[i][j]=++b[k].num

flag=0

n=0

continue

}

n++

}

if(b[k].num>9)

{

a[i][j]=b[k].num=0

k--

if(k<0)

{

printf("error!\r\n")

return -1

}

}

else

k++

}

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

{

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

{

printf("%d",a[i][j])

}

printf("\r\n")

}

return 1

}

先注意其中一个方格,限定该方格内可以填写的数字

注意其中一列(或者其中一个小九宫格),寻找填写某数字的方格。

学过计算机算法的人,可以尝试用回溯法试试。

数独的通解方法及步骤:

根据以下方法可以确保最终得到数独的解,而且通过手工运算的时间基本可以控制在1.5个小时,不论难易程度,所以此方法可以作为取得数独答案的一般解法。

1、根据横列、竖列和方格的限制条件排除各个点不可能的数字,并从1~9将各个可能的数字用小字体逐个写进每个空白的格子。(该步骤大约需要15~20分钟,这是求解的初始,务必确保没有遗漏)。

2、审视第一步骤的结果,如果发现某个空格只有一个数字,即确定该空格为这个数字。并根据该数字审视其相关的横行、竖列和方格,并划除相同的数字。(该情况出现的可能往往不多,除了较简单的数独题,但这是一个必要的过程,而且在随后的过程中要反复使用此方法。)

3、审视各个横行、竖列和方格中罗列出可能的数字结果,若发现某一个数字在各个横行、竖列或方格中出现的次数仅一次,则可以确定该空格的解为此数字。并根据第二条的方法排除与此空格相关列或方格中相同的数字。

4、审视各个横行、竖列和方格中罗列的各个可能的结果,找出相对称的两个数组合的空格(或3个、4个组合),并确定这两个空格(或3个、4个)的数字只可能为这两个数字,即两个数字在这两个空格的位置可以交换,但不可能到该行、该列或该方格的其他位置。根据此结果可以排除相关列或方格罗列出相关数字的可能,并缩小范围。(该步骤处理的难度相对复杂,需要在积累一定经验的基础上进行,也是最终求解的关键)

5、反复使用2、3、4提到的步骤,逐步得到一个一个空格的解,并将先前罗列的各种可能的结果一个一个排除,使可能的范围越来越小,直至得到最后结果。

另外一种方法解初级的题目比较简单,就是:

1、把每一个横行里缺少的数字写到这一行的最右边。

2、把每一个竖列里缺少的数字写到这一列的最下边。

3、在刚才写的备选数字中,肯定有一个是行和列都缺的,这个数就可以填到里面去了。

4、如此反复第3步即可。

数独用到计算的就是“45法则”:

每行的数字和=45

每列的数字和=45

每宫的数字和=45

而且数独计算一般只在Killer Sudoku才用,其它形式的题目不用

横排由上而下分别为 A-I,直排由左至右分别为1-9。

破解公式-1:利用同一排数字及同一九宫格内数字不能重复原则。要特别检视横线或直线三个九宫格内,有无两个相同的数字,就有机会为第三个找到定位。举例如下:

破解公式-2:注意任何一个九宫格内有直排或横排,全部空白时,与其他九宫格同一排相关联的数字,应该会出现在本九宫格的其他位置。举例如下:

注意F横排,由于F1-F3为空格,因此同一排的4, 6, 8, 数字,应该会在F1-F3的九宫格内的其他位置,也就是D1, D2, E3位置。由于I2=6, B2=4,E9=4因此D2=8, E3=6,D1=4。

破解公式-3:记得公式-1要经常再度检查运用,因为有些原有的空格已经出现数字,有机会可在相关空格填入数字。

破解公式-4:现在需要将九宫格内的空格可能数字,与其同一排的数字排除重复。记得要从较少格数作假设,然后在比对排除不可能的数字。(记得要横格,直格,九宫格互相比对)

一般高难度时,会需要用到5个空格,也就是只有4个数字出现。举例如下:

H横排剩余空格为1, 4, 5, 7而第5直排有4, 5, 7因此H5=1


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/12013475.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-20
下一篇 2023-05-20

发表评论

登录后才能评论

评论列表(0条)

保存