草庐IT

回溯算法解数独问题

unIlIl 2023-03-28 原文

好久没写算法了,浅解个数独

本篇代码以伪代码为主,主要讲解解题思路


规则介绍:

首先数独的游戏规则,每个九宫格 每一行 每一列 每个数字只能出现一次(1-9)

开局时会生成一些不能改变数字的格子

按规则填满所有格子为过关

图下所示为前几天朋友卡关了的状态:

例如第二行第一列有一个固定的5,在它的九宫格里就不能再出现另一个5

第二行也不能再出现5,第一列也不能再出现5


回溯思路:

我需要一个方法能够解这道题,我称呼他为方法A

需要调用方法A就能自动解开这道题,但是按照回溯算法的解题思路,方法A中的核心代码只需要解开一个格子的值,然后在下一个格子的位置再调用方法A

就有了如下伪代码:

布尔 方法A(int x,int y){
//此处先省略解开当前格子的代码 传入的参数为格子的坐标
返回 方法A(x,y+1);
}

这样的话,只需要调用方法A(0,0) 在解开一个格子后,他会自动去解下一个坐标的格子

最终返回true表示解开了这道数独,否则没解开

但是一行只有9个格子,一共9列,所以添加如下代码自动换行(添加到方法顶端,先判断是否越界再运行核心代码):

if (x > 8) {
    return true;
}
if (y > 8) {
    return 方法A(x + 1, 0);
}

现在这个方法已经会自动寻找下一个格子了

但是如果这个格子里的数值是不能修改的,就应该跳过这个格子

我的方法是开始运行前就遍历一遍格子,如果值不为0(开始求解前就有值),就把这个格子标记为不可变

if(此格子的数值不可变){
    return 方法A(x,y+1);
}

即使这里的y+1超过了下标上限,运行到下一个格子的时候也会自动修正


以上是部分回溯,当然后续还会根据情况修改

解题思路:

说明:我将开始解题前就有值的格子称为不可变格子,因为里面的值是固定的,不能改变

1、首先找到这个格子能填入的所有数值

以图中(0,0)为例,第0下标列中有5,4,1,7 第0下标行中有6,3,2 所在的九宫格中有5,1,7 所以这个格子只能填入8,9

提醒:

这个格子所在的九宫格里所有格子的特征:格子的行号除以3相等 格子的列号除以3相等

(左上角这个九宫格里的任何格子 行号除以3都为0 列号除以3都为0 而下面的九宫格行号除以3为1 列号除以3为0)

 

2、依次尝试能填的所有数字

先填入8,然后进行下一个格子,运行中如果发现下一个格子怎么填都不正确,说明前面的格子有存在错误的,则值清0,返回前面的格子,接着试下一个答案

例如:

(0,0)格子填入8,进入下一个格子 即调用了方法A(0,1) (0,1)格子中只能填入4,9 结果发现填哪个都不行,只能把自己重新赋值0 返回false

(0,0)接收到false 继续尝试下一个 尝试填入9 继续调用方法A(0,1)

以此类推,直到得到正确答案 如果所有值都试完了 都没有正确答案 则返回false

所以回溯部分的代码也需要一些修改

for(可填入的数字的集合){
格子(x,y)
=可填入的数字
if(方法A(x,y+1)){ return true; } }

运行起来大概是这个样子

如果得到正确的解,会从最后一个格子返回 true

而前面的格子都是使用if(方法A(x,y+1))调用的后面的格子

接收到true后也会返回true 直到最初的方法A(0,0)也返回true

如果所有的方案都无法得到解 尝试完所有方案后 也会依次返回false

 

有关回溯算法解数独问题的更多相关文章

  1. ruby - 在 64 位 Snow Leopard 上使用 rvm、postgres 9.0、ruby 1.9.2-p136 安装 pg gem 时出现问题 - 2

    我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po

  2. ruby - 通过 rvm 升级 ruby​​gems 的问题 - 2

    尝试通过RVM将RubyGems升级到版本1.8.10并出现此错误:$rvmrubygemslatestRemovingoldRubygemsfiles...Installingrubygems-1.8.10forruby-1.9.2-p180...ERROR:Errorrunning'GEM_PATH="/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/ruby-1.9.2-p180@global:/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/rub

  3. ruby - 通过 RVM (OSX Mountain Lion) 安装 Ruby 2.0.0-p247 时遇到问题 - 2

    我的最终目标是安装当前版本的RubyonRails。我在OSXMountainLion上运行。到目前为止,这是我的过程:已安装的RVM$\curl-Lhttps://get.rvm.io|bash-sstable检查已知(我假设已批准)安装$rvmlistknown我看到当前的稳定版本可用[ruby-]2.0.0[-p247]输入命令安装$rvminstall2.0.0-p247注意:我也试过这些安装命令$rvminstallruby-2.0.0-p247$rvminstallruby=2.0.0-p247我很快就无处可去了。结果:$rvminstall2.0.0-p247Search

  4. ruby - Fast-stemmer 安装问题 - 2

    由于fast-stemmer的问题,我很难安装我想要的任何ruby​​gem。我把我得到的错误放在下面。Buildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingfast-stemmer:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcreatingMakefilemake"DESTDIR="cleanmake"DESTDIR=

  5. ruby - 安装 Ruby 时遇到问题(无法下载资源 "readline--patch") - 2

    当我尝试安装Ruby时遇到此错误。我试过查看this和this但无济于事➜~brewinstallrubyWarning:YouareusingOSX10.12.Wedonotprovidesupportforthispre-releaseversion.Youmayencounterbuildfailuresorotherbreakages.Pleasecreatepull-requestsinsteadoffilingissues.==>Installingdependenciesforruby:readline,libyaml,makedepend==>Installingrub

  6. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

  7. ruby-on-rails - 简单的 Ruby on Rails 问题——如何将评论附加到用户和文章? - 2

    我意识到这可能是一个非常基本的问题,但我现在已经花了几天时间回过头来解决这个问题,但出于某种原因,Google就是没有帮助我。(我认为部分问题在于我是一个初学者,我不知道该问什么......)我也看过O'Reilly的RubyCookbook和RailsAPI,但我仍然停留在这个问题上.我找到了一些关于多态关系的信息,但它似乎不是我需要的(尽管如果我错了请告诉我)。我正在尝试调整MichaelHartl'stutorial创建一个包含用户、文章和评论的博客应用程序(不使用脚手架)。我希望评论既属于用户又属于文章。我的主要问题是:我不知道如何将当前文章的ID放入评论Controller。

  8. 【高数】用拉格朗日中值定理解决极限问题 - 2

    首先回顾一下拉格朗日定理的内容:函数f(x)是在闭区间[a,b]上连续、开区间(a,b)上可导的函数,那么至少存在一个,使得:通过这个表达式我们可以知道,f(x)是函数的主体,a和b可以看作是主体函数f(x)中所取的两个值。那么可以有,  也就意味着我们可以用来替换 这种替换可以用在求某些多项式差的极限中。方法: 外层函数f(x)是一致的,并且h(x)和g(x)是等价无穷小。此时,利用拉格朗日定理,将原式替换为 ,再进行求解,往往会省去复合函数求极限的很多麻烦。使用要注意:1.要先找到主体函数f(x),即外层函数必须相同。2.f(x)找到后,复合部分是等价无穷小。3.要满足作差的形式。如果是加

  9. 区块链之加解密算法&数字证书 - 2

    目录一.加解密算法数字签名对称加密DES(DataEncryptionStandard)3DES(TripleDES)AES(AdvancedEncryptionStandard)RSA加密法DSA(DigitalSignatureAlgorithm)ECC(EllipticCurvesCryptography)非对称加密签名与加密过程非对称加密的应用对称加密与非对称加密的结合二.数字证书图解一.加解密算法加密简单而言就是通过一种算法将明文信息转换成密文信息,信息的的接收方能够通过密钥对密文信息进行解密获得明文信息的过程。根据加解密的密钥是否相同,算法可以分为对称加密、非对称加密、对称加密和非

  10. SPI接收数据异常问题总结 - 2

    SPI接收数据左移一位问题目录SPI接收数据左移一位问题一、问题描述二、问题分析三、探究原理四、经验总结最近在工作在学习调试SPI的过程中遇到一个问题——接收数据整体向左移了一位(1bit)。SPI数据收发是数据交换,因此接收数据时从第二个字节开始才是有效数据,也就是数据整体向右移一个字节(1byte)。请教前辈之后也没有得到解决,通过在网上查阅前人经验终于解决问题,所以写一个避坑经验总结。实际背景:MCU与一款芯片使用spi通信,MCU作为主机,芯片作为从机。这款芯片采用的是它规定的六线SPI,多了两根线:RDY和INT,这样从机就可以主动请求主机给主机发送数据了。一、问题描述根据从机芯片手

随机推荐