求这道数独题目中级的解法

专业文档是百度文库认证用户/机構上传的专业性文档文库VIP用户或购买专业文档下载特权礼包的其他会员用户可用专业文档下载特权免费下载专业文档。只要带有以下“專业文档”标识的文档便是该类文档

VIP免费文档是特定的一类共享文档,会员用户可以免费随意获取非会员用户需要消耗下载券/积分获取。只要带有以下“VIP免费文档”标识的文档便是该类文档

VIP专享8折文档是特定的一类付费文档,会员用户可以通过设定价的8折获取非会員用户需要原价获取。只要带有以下“VIP专享8折优惠”标识的文档便是该类文档

付费文档是百度文库认证用户/机构上传的专业性文档,需偠文库用户支付人民币获取具体价格由上传人自由设定。只要带有以下“付费文档”标识的文档便是该类文档

共享文档是百度文库用戶免费上传的可与其他用户免费共享的文档,具体共享方式由上传人自由设定只要带有以下“共享文档”标识的文档便是该类文档。

}

数独(Sudoku)是一种运用纸、笔进行演算的逻辑游戏玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字并满足每一行、每一列、每一个粗线宫内的数字均含1-9,不重复 每一道合格的数独谜题都有且仅有唯一答案,推理方法也以此为基础任何无解或多解的数独题目中级都是不合格的。

如下图所示就是一个数独的数独题目中级

关于数独的详细介绍,参看“”

数独的基本解法就是利用规则的摒弃法

每一行称为数独的每一列稱为数独的,每一个小九宫格称为数独的数独的基本规则就是每一行、每一列、每一宫中,1-9这9个数字都只出现一次

用(行,列)表示上图的单元格例如(1,1)表示第一行第一列的单元格(2,4)表示第二行第四列的单元格

如上图每个空白单元格中能填的数字都昰有限制的。

例如:(11)就只能填7和8;而(6,4)只能填8;

那些只能填一个数字的空白单元格,我们称之为唯一数单元格上图中(6,4)就是唯一数单元格

解题的顺序就是从唯一数单元格开始,由于唯一数单元格只能填一个数故先在这个单元格里填数。在这个单元格裏填数由于规则的定义,那么这个单元格所在的行、所在的列、所在的宫的其他单元格就不能再填这个数了这些单元格能填的数的可能性就少了。有可能会产生新的唯一数单元格

在相当的一些的数独数独题目中级中,从唯一数单元格开始填数不停的在唯一数单元格填数就可以把数独解出来。

如果在解题的过程中发现某些空白单元格没有数字能填这样的单元格称之为无解单元格,那就说明:要么这個数独没有解;要么之前的解题过程有问题需要返回检查之前的解题过程查看。

但是还有不少的数独的数独题目中级在解题的过程中,在还有空白单元格的情况下却找不到唯一数单元格,也就是意味着每个空白单元格中能填的数字至少有2个我们称之为无唯一数单元格的状况

这个时候怎么办?我们找到其中一个可能数最少的空白单元格(这个没有定论可以是可能数最少的空白单元格;也可以是第一個空白单元格;也可以是可能数最多的空白单元格,选哪个空白单元格对后面的解题是否有影响没有证明过,不好妄下定论凭感觉选鈳能数最少的空白单元格是最好的选择),由于能填的数字不止一个先把当前的状态保存起来,再在能选的数字中选择一个数字填写(從小到大选择)然后继续求解下去。如果能解出最后的结果说明当前的选择是正确的;如果后面的求解过程有问题,说明当前的数字嘚选择有问题那么再挑选另一个数填写,继续求解如果,所有的选择都求不出最后的结果还是说明:要么这个数独没有解;要么之湔的解题过程有问题,需要返回检查之前的解题过程查看如此反复,直到求出最终的答案

会有种极端的情况(可能性不大)。那就是茬当前的空白单元格的所有可能的数字都选择了一遍都没有解。而之前又没有出现无唯一数单元格的状况那就说明这个数独根本就没囿解

下图是数独求解的流程图

下面谈谈该算法的具体实现

用计算机来求解数独。基本的一点就是如何表示数独的状态

用整形一维数组来表示数独的状态

用Num(80)表示数独的状态(数组的下标从0开始),数独是一个二维表格而数组是一维数组。那么就存在一维和二维之间的轉换

一维数组的下标Index(小标从0开始)和二维下标X、Y(下标从0开始)之间的转换公式

数组中的每个整数表示数独对应的单元格的状态

正数表礻空白单元格能填的数的组合用二进制表示。用位来表示该单元格是否能填相应的数字1表示能填,0表示不能填

如文章开始的数独的單元格(1,1)可能填7和8则第7位和第8位上是1(位数是从后往前数),其余位都是0用整数表示就是Num(0)=2=192

每在单元格中填一个数字,则把相應的行、列、宫中其余的单元格把该数字去掉

我们可以充分利用位运算来简化去数字的过程。如:要把单元格去掉7这个数字的可能首先7对应的二进制位2,取其反数得到2再和目标单元格的数值进行AND的位运算,来实现去除该单元格7这个数字的可能性(由于位运算的便捷鈈需要考虑该单元格是否原本包含7这个数字的可能性)。

如:(11)=2 AND 2=2,去除7这个可能性只剩8这个可能性了,也就是成为唯一数单元格

再仳如:(19)=2 AND 2=2,原本单元格就没有7这个可能性执行位运算后,还是原来的可能性没有发生变化。

负数表示该单元格已经确定的数例洳:(1,2)=-6表示该单元格已近填了数字6

0表示该单元格既没有填确定的数字,也没有可填数的可能性也就是上文说的无解单元格

为了算法中计算的方便,事先把这些二进制数都缓存起来用一个一维的数组表示

用数组V来表示各个位对应的数字

数字7对应的二进制数为V(6)=2=64,7嘚反数为V(9)-V(6)=2=447

每个单元格初始的值都是V(9)=2=511

2、如何获得一个单元格的可填数的个数

由于是用二进制来表示单元格的状态那么可填数嘚个数就是该数字中1的个数。我们之前有一个很方便的方法快速计算一个数中1的个数参看。

依据之前的说法在碰到无唯一数单元格的凊况时,要把当前的状态缓存起来考虑到实际情况,从算法的角度上来说用栈(先进后出)这个数据结构来实现比较合适。可以自己寫一个栈的实现但是,目前很多的编程语言都实现了基本的数据结构提供了基本的数据结构的类和方法供我们调用。

以Visual Studio为例它有Stack这個类,实现了栈的基本操作有两个栈的方法:Push(压栈)——把数据写到栈里面;Pop(出栈)——把数据从栈里提出来,并删除栈中的数据

该数独还是比较简单的,一路唯一数单元格到底

下面是该算法类的完整代码

}

我要回帖

更多关于 数独题目中级 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信