网站大量收购独家精品文档,联系QQ:2885784924

[计算机]《猜图游戏》解题报告.doc

  1. 1、本文档共14页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
[计算机]《猜图游戏》解题报告

作者声明: 此题所附程序,深搜是正确的,会输出所有解。简单推理程序有误。 《猜图游戏》解题报告 By sx349 【摘要】 核心算法思想:深搜/数学推理 主要数据结构: 其他辅助知识: 时间复杂度:(深搜,显然在强剪枝下常数极小) /(推理,常数也很小) 空间复杂度:(常数极小) 【题目大意】 给定一系列规则和一系列数据,根据规则通过简单推理还原图像。 (“简单推理”的定义为,仅考虑某一行(列)的信息以及该行(列)中已知的方块的颜色,推理出该行(列)中更多方块的颜色。) 【算法分析】 尽管一开始就看到了简单推理这句话,但是一开始并没有想到有效利用这一条件的方法,于是先考虑到用深搜的做法,配合强剪枝来解决。 显然,深搜也有好几种做法,可以先搜索行,也可以先搜索列:(以搜索行为例) 假设我们搜索到第I行: 对每一列维护一个表,搜索到第I行的第J个格子,将这一个各自的状态加入这个表,并且对这个列的表与这个列的状态进行比对。这是一个很普遍的剪枝,显然,这个剪枝的关键在于如何维护这个表。 因为这个表中有三种状态:填0(代表白格),填1(代表黑格),以及填-1(代表未确定)。在一开始考虑的时候,我先把所有已经确定的行和列都填好,因此就必须把-1和0区别开来,但是为了接替方便,最后还是将这些已经确定的行作为搜索时的小剪枝,而避免了-1和0的区分,因此,表的状态就只要用一个布尔数组来判断一下就行了。 但是布尔数组每次的判断还是要的复杂度,在深搜的过程中如果每一步都判断,那么就必然会超时。因此需要有更好的方法维护这个表。 显然,每一列所要求的数字排列是有序的,那么,对于每一列我们都可以用两个数字M,N来表示当前该列的状态,即已经判断了该列的前M个数,并且第M+1个数已经检查了N格(显然N是小于第M+1个数的)。如果当前我们判断这一格是白格,那么判断之前的状态中N是否等于第M+1个数,如果等于,则M加上1,N归零,否则如果小于,则显然不可行,回溯;如果当前我们判断这一个是黑格,那么判断之前的状态中N+1是否超过第M+1个数,如果超过,那么不可行,如果不超过,那么N加上1;当判断完整张表之后,相当于在整张表之下全部添加一列白格,在对每一列进行判断。这样每次的判断复杂度就只有了。 那么如何来搜索某一行的状态呢? 我们用J,K两个数来表示我们搜索到这一行中的第J-1个空当,且这个空当的长为K。当然,在这里也可以搜索黑格,但是搜索空当的优势在于我们可以在每一行之前和之后都添加一个白格,这样就可以确定空当的开始和结束,而黑格就无法这样做了。搜索空当之后,将空当中的每一个白格都进行一次判断,然后对这个空档之后的一段黑格再逐个进行判断。但是我们又面临了这样一个问题:如何在退出当前层回溯时恢复数据呢?因为层数过深(理论最高900层),所以无论是值参还是局部变量都会成为累赘(毕竟系统栈不深)。因此,我又另开了一个数组,来记录每一步的推理结果。 至此,深搜的算法已经大体完成,基本上20*20的数据可以秒杀并且输出所有解,暂时因为没有30*30的数据来进行极限测试,但是由于题述中说是保证唯一解,因此应该能够在时限内得到这一组解。 经过与张若愚的讨论和借鉴,我又重新开始研究了简单推理的办法。(还是以行为例) 显然,正如我上面所提到过的,有些行和列是可以直接确定下来的。那么,这些行和列已经确定的格子就相当于我们的初始数据。建立一个队列,将这些已经确定的格子加入这个队列,然后进行如下的操作。 首先是预处理,对于每一行(或列),我们可以算出所有它可能有的排列。假设我们已经根据第I行的数字,得到了第I行的所有排列,将它们列成一张表。 从队列中取出某个确定的格子,将它所在的行(或列,取决于这个格子之前是由行的分析判定还是由列的分析判定的),这样,除了我们已经确定的几个格子之外,有可能在所有的排列中,某一格始终为白格(或黑格),那么马上就可以判定这一格是白格,然后将这一判断入队,重复这一过程。 显然,这完全符合上述“简单推理”的定义:仅考虑某一行(列)的信息以及该行(列)中已知的方块的颜色,推理出该行(列)中更多方块的颜色。而且,如果是做为手工笔算小数据的方法,显然是很好的(尤其是这种描述很符合思维习惯)。但是,如何在电脑上实现这一过程呢? 我们再次建表,不过,这一次不是建一张,而是对每一行都建两张表,其中横里是这一行的每一个格子位置,竖里是这一行的每一种排列方式。对于横里和竖里的开头都建一个Head。 其中,前一张表中的每一个结点(除了Head之外),都是判断中的当前行的可能排列中黑格的位置,后一张表则为白格的位置。这样,我们就可以很轻松的判断某一个是否在所有排列中保持同样的性质了:如果黑格表中某一列的Head直接指向NIL,则这一列必然都是代表白格,反之,白格表中同样的情况

文档评论(0)

qiwqpu54 + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档