华容道游戏的人工智能搜索解法
数字华容道技巧

数字华容道技巧引言数字华容道是一种智力游戏,通常由一个包含数字的方形棋盘构成。
游戏的目标是通过移动数字块的位置,将它们按照从小到大的顺序排列在棋盘上。
本文将介绍一些使用的技巧和策略,帮助你快速解决数字华容道难题。
基本策略下面是一些常用的基本策略,可以帮助你在数字华容道中取得更好的成绩:1.寻找空白块:首先要找到空白块的位置。
通过观察数字块的移动范围,找到空白块所在的位置,可以帮助你规划移动的策略。
2.确定目标数字块:目标数字块是指在你进行移动时要集中注意力的数字块。
通常情况下,目标数字块是当前与空白块相邻的数字块。
将目标数字块移动到空白块的位置,可以为你的策略提供更多的可能性。
3.使用逆序对法则:逆序对法则是指通过观察数字块的排列顺序,来判断数字华容道是否能够解决。
如果逆序对的数量是偶数,那么问题有解;如果逆序对的数量是奇数,那么问题无解。
4.避免移动目标数字块:在移动目标数字块时,尽量减少其他数字块的移动次数。
这样可以避免不必要的混乱,提高解题效率。
高级技巧除了基本策略外,还有一些高级技巧可以帮助你更快地解决数字华容道难题。
1.使用模式识别:通过观察数字块的排列规律,你可以发现一些模式。
这些模式可以帮助你更好地掌握数字块移动的策略。
例如,当数字块的排列呈现对称性时,可以通过交换数字块的位置来改变对称性,进而使解决问题更加容易。
2.尝试多种可能性:如果你遇到了一个棘手的数字华容道难题,不要放弃!尝试尽可能多的移动策略,尝试不同的数字块排列方式。
持续尝试不仅可以帮助你找到最佳解决方案,还可以培养你的观察力和逻辑思维能力。
3.思考局部最优解:在解决数字华容道问题时,你不一定需要找到全局最优解。
有时,只需找到局部最优解,再通过一系列的局部最优解,逐步接近全局最优解。
这种方法可以减少解题的复杂性,更容易找到解决方案。
结论数字华容道是一款富有挑战性的智力游戏。
通过运用基本策略和高级技巧,我们可以更有效地解决数字华容道问题。
《最强大脑》第五季中第一轮比赛“数字华容道”解题思路

《最强大脑》第五季中第一轮比赛“数字华容道”解题思路《最强大脑》第五季中第一轮比赛“数字华容道”解题思路《最强大脑》是江苏卫视借鉴德国节目《Super Brain》推出的国内首档大型科学类真人秀节目,是专注于传播脑科学知识和脑力竞技的节目。
自2014年第一季开播以来备受关注。
2018年1月5日第五季开播,令大批粉丝的目光再次转向江苏卫视。
和以往不同,第五季第一期第一轮就展开了百人大战百人大战的题目很简单,但也非常考验选手的综合能力,特别是逻辑思维能力,思维稍有停滞,名次就相去甚远。
我小时候玩过这种游戏,忽然在《最强大脑》中出现,让我很以外,但也让我对这个小游戏重新提起了兴趣,就玩了几遍,下面介绍一下数字华容道一般分为三种:3×3、4×4和5×5,这三种难易程度都是相同的,只是复杂成都不同,无论是4×4还是5×5,最后重点都将落在其中的3×3的9个方格内,所以以3×3为例进行分析游戏时,如果脑容量够大,可以同时对整体进行位置分析,会少用很多步骤,用时当然也会很短。
但对一般人来说,首先是对第一排1-3的位置进行排序,不需要考虑第二排和第三排的位置,所以第一排的排序最为简单,不再赘述。
在第一排完成后,第二、三排有两类可能性:第一类:有三种排列的可能性,其实这三种是一样的,只不过变了下形式第二类:算是已经完成的类型,有三种排列的可能性,其实这三种是一样的,只不过变了下形式严格来说,这两类也算是同一种,因为随便几步挪动就能使其相互转换(只不过变了下形式),但为了不让刚接触的人不觉得那么扯淡,就且给它分个类。
越写越觉得没什么可写的,多玩两遍就能找到规律。
直接插入动态图得了。
下面两个图在word里不会动,下载word后,把两个图另存在电脑上就可以看到动态效果。
第一类解题第二类解题:本图是把7、8放在6#位和9#位调整4、5、6的,如果把7、8放在4#位和7#位调整4、5、6,步骤会更少。
华容道游戏的解法

华容道游戏的解法最早系统研究游戏华容道的是苏州大学数学教授许莼舫先生。
1952年,他在《数学漫谈》中对这个游戏作了详细的分析,总结出8条规则。
这8条可以归纳为以下4点:1,四个小兵必须两两在一起,不要分开;2,曹操,关羽,大将移动时前面应有两个小兵开路;3,曹操移动时后面还应有两个小兵追赶;4,以下三种状况,其中各块都可局部(不妨碍其他地方)任意移动。
在此基础上,许莼舫提出了100步解法。
后来,美国一个律师托马斯.莱曼(Thomas B.Lenann)发现一个新的解法,由加德纳公布在1964年3月《科学美国人》上,有81步,称加德纳解法。
游戏华容道有不同的开局,根据5个矩形块的放法分类,除了5个都竖放是步可能的以外,有一横式,二横式,三横式,四横式,五横式。
下面举几个例子。
研究华容道游戏,除了其历史外,至少有以下几个问题:1,有多少种开局;2,判断有解;3,给出最优解;4,计算机求解。
因此,华容道是个数学游戏。
国内国外都有一些华容道的爱好者研究者。
姜长英先生1985年发起组织“华容道研究会”,他们有了不少结果。
特别是原北京工业学院副院长齐尧的网络研究,可以说完全解决了华容道游戏方法。
他研究了一横式华容道的各种关键状态共54图,找出其间关系,画出关系图。
于是任何一横式华容道都可以经少数几步到达某一个关键状态,其解法也就给出了。
对二横式,三横式,四横式,他也都画出了关系图。
用计算机解决华容道游戏,/html/sxjm/examples/ex5.htm上有这样的说法:“笔者编制的软件HRDE的贡献是成功地实现了一种系统搜索(Systematic searching)算法,它能在较短时间内,对用户摆放的任何一种布局判断是否有解。
如果有解,则解出它的最少步法。
然后,它会在屏幕上用动画方式移动棋子以显示它的运算方法。
也可以用一连串的图形来静止地显示每一步的走法,便于用户仔细地观察研究。
一般情况下,在已经很普及的IBM486计算机上解一道题仅需要一两分钟,在较慢的286计算机上则大约需要十几分钟。
数字华容道算法

数字华容道算法1.什么是数字华容道算法?数字华容道算法是一种常见的问题解决方案,以数字版华容道游戏为基础。
该游戏包括一个9x9的棋盘和15个方块,每个方块都有一个唯一的数码,从1-15。
目标是将这些拼图方块移动到背景网格中的特定位置,使它们按升序排列。
数字华容道算法就是为了解决如何最优地解决这个问题。
2.数字华容道算法如何工作?数字华容道算法是一种基于搜索的解决方案,但是有许多不同的搜索算法可以使用。
其中最常见的算法是广度优先搜索(BFS)和A*搜索。
BFS算法以深度优先搜索遍历棋盘中的所有可能状态,并保存每个可能状态的步数,直到找到最终状态并返回路径。
相反,A*算法通过计算两个因素来决定搜索行进的方向:步数和从当前状态到最终状态的估计成本。
A*算法会通过比较不同状态的估计成本,来决定下一步应该朝哪个方向移动。
3.数字华容道算法的优点和缺点?数字华容道算法优点是可以对每个局面进行无差别的搜索,从而找到解决问题的最短路径。
缺点是计算量较大,因为它必须检查所有可能的状态。
此外,由于游戏的大小和随机性,会影响到搜索算法的效率。
4.数字华容道算法在实际应用中的作用?数字华容道算法可以用于其他问题,如找到迷宫中的最短路径,以及在物流等领域中优化运输。
该算法也被用于解决机器人空间路径规划问题、DNA测序和生物信息学等领域的优化问题。
5.总结数字华容道算法是一种基于搜索的解决方案,可以用于解决类似数字华容道游戏的优化问题。
它可以通过BFS或A*算法,找到解决问题的最短路径,但在实际应用中需要考虑问题的规模和随机性,从而优化算法的效率。
该算法在机器人路径规划、DNA测序和物流优化等领域都有着广泛的应用。
一种改进的广度优先求解华容道问题的方法

摘ቤተ መጻሕፍቲ ባይዱ
要: “ 华容道”是 中国传统的拼版类游戏。本文通过对华客道 求解 问题的分析 ,提 出高效且方便 的布局表
容道 问题。通过 实验证 明:该改进方法不但具有很好 的求解效率 ,而且性 能不会随 问题复杂度的增加
而骤 降 。
关键 词 : 人 工智 能:广度 优 先搜 索 : 容道 ; a h o e 华 H s C d
张
飞
曹 操
马
超
赵
— —
关羽
/ 、
黄
丘 兵 忠
/ 丘 \ 兵
日本藤村幸三郎曾在 《 数理科学 》杂志上发表华容道
① 基金 项 目: 叶斯分类 器与 判别式 学 习方 法研 究(0 3 0 贝 6 87 1 ) 0 收稿 时 间:0 — 3 0 : 到修改稿 时 间:0 - 4 0 2 1 0 — 5收 0 2 1 0—1 0
张 曹操 马 马 曹操 张 飞
— —
超 超
— —
飞
赵 关羽 黄 赵 关羽 黄
百 g 丘 思 i 丘 丘 思 、 - 、 、 、
g -
、
非递 归深度 优先算法对华容道进行求解 ,但 其遍历所 得 到的首解并不是 问题的最优解 ,需要进 一步遍历找 出最优 解。若问题需要快速地给 出一个 可行解 ,相信 深度优 先算法是一个不错 的选择 。但本 文研 究的 目的 是应 用计 算机对每种布局快速地找到最优 走法或判断 它无解 ,因此本文采用 了改进的广度优 先算法进行求
meh di ey e c e t y i n igt ea s r t o sav r f in i wa f dn we . ni h n
华容道的解法思路和方法

华容道的解法思路和方法嘿,朋友们!今天咱就来聊聊华容道这玩意儿。
华容道啊,就像是个小小的智力迷宫,看似复杂,其实只要找对了路,就能轻松走出来。
你看啊,那曹操就像是在迷宫里迷路的家伙,被各种大将小兵给困住啦。
而我们呢,就是要想办法把曹操给解救出来。
这可不是件容易的事儿,但也绝对不是不可能完成的任务。
咱先来说说这解法思路。
就好比你在一个陌生的地方找路,你得先有个大致的方向吧。
在华容道里,你得观察那些棋子的位置,想想怎么移动才能让曹操一步步地挪出来。
有时候你得大胆地尝试,别怕走错,大不了再重新开始嘛!就像人生一样,谁还没走过几条错路呀,但只要不放弃,总能找到对的方向。
然后就是具体的方法啦。
比如说,先把那些容易移动的棋子挪开,给曹操腾出点空间来。
这就好像是在清理道路上的障碍物,让路变得更通畅。
再看看有没有什么可以形成连锁反应的移动,一下能带动好多棋子一起动,那可就太棒啦。
有时候啊,你得有点耐心,别着急。
就像钓鱼一样,得静静地等着鱼儿上钩。
在华容道里,可能你得慢慢地挪动那些棋子,一步一步地接近目标。
可别小瞧了这每一步哦,也许就是这小小的一步,就能让局面豁然开朗呢!你想想,要是你一下子就把曹操解救出来了,那得多有成就感啊!这可比玩那些电子游戏有意思多了吧。
这可是真正考验你脑子的时候呢!而且啊,玩华容道还能锻炼你的观察力和思维能力。
你得眼观六路,耳听八方,才能找到最佳的解法。
这就像是在生活中,你得时刻留意周围的变化,才能应对各种情况呀。
还有哦,你可以和朋友们一起玩华容道呀,比比谁解得快。
这多有意思呀,既能增进感情,又能一起享受解谜的乐趣。
哎呀,这可比一个人闷着头玩有意思多啦!总之呢,华容道就是个充满挑战和乐趣的小游戏。
只要你用心去玩,肯定能找到属于自己的解法。
别犹豫啦,赶紧去试试吧!让我们一起在华容道的世界里畅游,解救那被困的曹操吧!相信自己,你一定行!。
华容道及解法图解(转载)
华容道及解法图解(转载)
这是⼀个由经典的故事发展⽽成的益智玩具。
⿅港“曹瞒兵败⾛华容,正与关公狭路逢。
只为当初恩义重,放开⾦锁⾛蛟龙”。
这⾸诗是《三国演义》⾥,作者对⾚壁之战关公放⾛曹*的感慨。
“华容道”这⼀古⽼的智⼒游戏,就取意于这段故事。
由于该游戏变化多端,精深莫测,具有百玩不厌等特点,被称为世界“智⼒游戏界的三⼤不可思议的游戏”之⼀。
棋⼦的游戏规则是:只准利⽤2个空平⾯移动,不许把棋⼦重叠,也不许跨过任何棋⼦,要想法⽤最少的步数把曹*移到出⼝。
只许曹*出去,别的棋⼦不许出去。
本游戏的⽬的就是通过移动各个棋⼦,帮助曹*从初始位置移到棋盘最下⽅中部。
⾸先规定⼀下棋⼦的名称:最⼤的“曹”,横着放的“关”,竖着放的“飞”(张、赵、马、黄都称之为“飞”),最⼩的“兵”。
横⼑⽴马解法共81步。
华容道游戏的人工智能搜索解法
华容道游戏的计算机搜索求解1.绪论“华容道”有几十种布阵方法,如图1给出的“横刀立马”、“层层设防”、“过五关”、“水泄不通”、“峰回路转”等等玩法。
棋盘上仅有两个小方格空着,玩法就是通过这两个空格移动棋子,用最少的步数把曹操移出华容道。
这个玩具引起过许多人的兴趣,大家都力图把移动的步数减到最少。
图(1)2.计算机搜索的算法2.1盘面的表示方法在编写程序之前,首先要确定华容道每个盘面在计算机内存中的存储格式。
由上面的介绍看到,华容道的盘面为五行四列,棋子分为五种(把空白处也视为棋子),所以可将盘面的棋子进行编号后存储在一个5×4的二维数组中。
在不同的开局中,可能会有多种“关羽”或者多种“张飞”,编号时只要棋子的形状相同就采用相同的编号,具体编号方式如图2。
这样,“横刀立马”开局就可存储成图3的方式。
图(2) 图(3)在给定盘面中寻找下一步有哪些走法时,首先要确定当前盘面中空白处的位置,然后判断与空白位置相邻的棋子能否向空白位置移动。
在程序中若要得到当前盘面的下一个盘面,首先要找到两个0的位置,再看这两个0的四周的棋子中有那些可以向0移动。
还以“横刀立马”开局为例,显然两个0分别在下标为[4][1]和[4][2]的存储单元中,周围共有四个4可向0移动,即有四种走法。
2.2搜索方法的选择解决华容道问题就是要在给定开局盘面的情况下,按照棋子的移动规则,最终将曹操移动至最下方的出口位置,而移动的步数越少越好。
将华容道游戏中每一个盘面视作一个节点,采用广度优先搜索(BFS )的方式,这样第一个找到的解一定是最佳解。
为了避免搜索进入循环以致无法继续搜索下去,在每次展开儿子节点时都检查此儿子节点之前有无出现过,仅保存之前没有出现过的儿子节点。
另外,在搜索到目标节点后,还要能够找出从初始节点通往目标节点的通路,这是一个回溯的过程。
所以,每次由当前节点生成儿子节点时,还要给儿子节点标记上父亲节点的位置。
25个数字华容道解法
25个数字华容道解法华容道是一种古老的益智游戏,它的目标是将一组数字按照特定的规则移动,最终使得数字按照从小到大的顺序排列。
本文将介绍25个数字华容道的解法,帮助读者更好地理解和掌握这个游戏。
解法一:将数字1移动到最左上角,然后按照顺时针方向移动数字,直到数字25移到最右下角。
解法二:将数字25移动到最右下角,然后按照逆时针方向移动数字,直到数字1移到最左上角。
解法三:以数字12为中心,将数字1至9移动到左上角、左中、左下角位置,将数字13至21移动到右上角、右中、右下角位置,最后将数字10、11、22、23、24、25移动到中间位置。
解法四:将数字1至5移动到左上角位置,将数字6至10移动到右上角位置,将数字11至15移动到左下角位置,将数字16至20移动到右下角位置,最后将数字21至25移动到中间位置。
解法五:先将数字1至5移动到左上角位置,然后将数字6至10移动到右上角位置,再将数字11至15移动到右下角位置,最后将数字16至25移动到左下角位置。
解法六:以数字13为中心,将数字1至12移动到左上角、左中、左下角位置,将数字14至25移动到右上角、右中、右下角位置。
解法七:将数字1至9移动到左上角、左中、左下角位置,将数字10至18移动到右上角、右中、右下角位置,最后将数字19至25移动到中间位置。
解法八:将数字1至9移动到左上角位置,将数字10至18移动到右上角位置,将数字19至25移动到右下角位置,最后将数字10、11、12、13、14、15、16、17、18、19、20、21、22、23、24、25移动到中间位置。
解法九:将数字1至6移动到左上角位置,将数字7至12移动到右上角位置,将数字13至18移动到右下角位置,将数字19至24移动到左下角位置,最后将数字25移动到中间位置。
解法十:将数字1至6移动到左上角位置,将数字7至12移动到右上角位置,将数字13至18移动到右下角位置,将数字19至24移动到左下角位置,最后将数字25移动到中间位置。
华容道公式
华容道公式摘要:一、华容道的起源与历史1.华容道的背景与起源2.华容道在我国的发展历程二、华容道公式及解法1.华容道公式的定义2.标准华容道公式的解法3.非标准华容道公式的解法三、华容道在人工智能中的应用1.华容道与人工智能的结合2.人工智能在解决华容道问题上的优势四、华容道在我国的影响及意义1.华容道对我国民间智力游戏的影响2.华容道对人工智能技术发展的推动作用正文:华容道作为一款起源于中国的古老智力游戏,拥有着悠久的历史与丰富的文化内涵。
其起源可以追溯到三国时期著名的“曹操败走华容道”的故事。
在华容道的发展历程中,逐渐形成了现今我们所熟知的游戏规则与解法。
华容道公式,作为解决华容道问题的核心,是一种描述棋盘上物体移动规律的表达式。
其中,标准华容道公式是指物体在移动过程中,每一步都只能向一个方向移动,而非标准华容道公式则在此基础上允许物体进行斜向移动。
在解决华容道问题时,通常需要运用到诸如递推、回溯等算法。
其中,递推算法是解决华容道问题的重要方法,其基本思想是将问题分解成规模较小的子问题,并通过求解子问题来逐步解决原问题。
此外,回溯算法也是解决华容道问题的一种有效手段,其核心思想是从一条路往前探索,当发现此路不通时,就回退到上一个节点,再选择一条新路继续探索。
随着人工智能技术的发展,华容道问题逐渐成为人工智能领域的研究热点。
研究者们通过将华容道问题建模为深度学习、强化学习等问题,使人工智能助手能够成功地解决华容道问题。
这不仅为华容道问题的求解提供了新的思路,同时也为人工智能技术的发展提供了有力支持。
总的来说,华容道在我国的影响深远,不仅丰富了民间智力游戏的文化内涵,而且对人工智能技术的发展起到了积极的推动作用。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
华容道游戏的计算机搜索求解1.绪论“华容道”有几十种布阵方法,如图1给出的“横刀立马”、“层层设防”、“过五关”、“水泄不通”、“峰回路转”等等玩法。
棋盘上仅有两个小方格空着,玩法就是通过这两个空格移动棋子,用最少的步数把曹操移出华容道。
这个玩具引起过许多人的兴趣,大家都力图把移动的步数减到最少。
图(1)2.计算机搜索的算法2.1盘面的表示方法在编写程序之前,首先要确定华容道每个盘面在计算机内存中的存储格式。
由上面的介绍看到,华容道的盘面为五行四列,棋子分为五种(把空白处也视为棋子),所以可将盘面的棋子进行编号后存储在一个5×4的二维数组中。
在不同的开局中,可能会有多种“关羽”或者多种“张飞”,编号时只要棋子的形状相同就采用相同的编号,具体编号方式如图2。
这样,“横刀立马”开局就可存储成图3的方式。
图(2) 图(3)在给定盘面中寻找下一步有哪些走法时,首先要确定当前盘面中空白处的位置,然后判断与空白位置相邻的棋子能否向空白位置移动。
在程序中若要得到当前盘面的下一个盘面,首先要找到两个0的位置,再看这两个0的四周的棋子中有那些可以向0移动。
还以“横刀立马”开局为例,显然两个0分别在下标为[4][1]和[4][2]的存储单元中,周围共有四个4可向0移动,即有四种走法。
2.2搜索方法的选择解决华容道问题就是要在给定开局盘面的情况下,按照棋子的移动规则,最终将曹操移动至最下方的出口位置,而移动的步数越少越好。
将华容道游戏中每一个盘面视作一个节点,采用广度优先搜索(BFS )的方式,这样第一个找到的解一定是最佳解。
为了避免搜索进入循环以致无法继续搜索下去,在每次展开儿子节点时都检查此儿子节点之前有无出现过,仅保存之前没有出现过的儿子节点。
另外,在搜索到目标节点后,还要能够找出从初始节点通往目标节点的通路,这是一个回溯的过程。
所以,每次由当前节点生成儿子节点时,还要给儿子节点标记上父亲节点的位置。
这样就可以从最终找到的目标节点回溯到初始节点,从而找到初始节点与目标节点之间的通路。
2.3主要变量数组history :存储由初始向量展开的解空间; 数组start :存储初始节点;数组connection :存储解空间中每个节点生成子节点的方式,其中每一行记录下一步移动的棋子和棋子的坐标以及移动方向等信息;数组father :存储解空间中每个节点的父亲节点的位置; 数组width :存储解空间每一行的宽度;数depth:存储解空间的深度3.程序执行结果程序在一台普通的笔记本电脑上执行:Intel Core i3M370处理器,主频2.4GHz,1.86GB可用内存。
使用MS Visual Studio 2010的C语言环境,源程序代码约210行,以下为程序在开头给出的八种开局为例分别得出的运行结果。
表1 给定不同开局下的程序运行结果4.反思与展望4.1程序的改进由于时间仓促,程序中有很多需要改进的地方,主要有以下几方面:改进搜索方法。
如在节点开展程度较深时(如100层以上),改用深度优先搜索以节约搜索时间和存储空间。
还可以采用A*算法提高搜索效率。
改进判断重复的方法。
因为华容道棋盘左右对称,如果开局时的棋子布局也左右对称(如“横刀立马”开局),可将左右对称的节点看作是重复节点不予展开,从而大为减少搜索在时间和空间上的消耗。
优化存储。
可以将每个盘面进一步缩减到更小存储格式中去;优化解空间的存储。
在本程序中定义的history[200][3000][5][4]浪费了大量的存储空间,可改用形如history[N][5][4]这样的线性的空间存储各节点。
4.2将来需要研究的问题在本程序的基础上,可以进一步研究以下问题:华容道问题一共有多少种开局,其中有解开局有哪些,每种有解开局的最佳解,最难的开局是什么。
附录:全部程序代码和程序运行结果截图(以“横刀立马”为例)#include<stdio.h>#include<math.h>#include<time.h>#include<stdlib.h>static int x,y,route[200][5][4]={0},branch_num[200][3000],depth,father[200][3000];static int history[200][3000][5][4]={0},connection[300][3000][8][8]={0};static int temp[5][4];static long width[200]={0};int form_connection();void block_nearby_single(int m, int n,int dir);void block_nearby_bouble(int x1,int x2,int y1,int y2);void write_block_nearby(int a,int b,int x1,int x2,int y1,int y2,int dir,int h);void print_history(int p,int q);void print_connection(int p,int q);void move(int t);int compare_temp_and_history();void write_temp_to_history(int x1,int y1);void print_route(int p);void write_route(int p,int q);void main(){ int i,j,t,q,p,m=0,l,s;long plot_sum=-1;typedef long clock_t;clock_t startt,finisht;double duration;startt=clock();int start[5][4]={31,11,12,31,32,14,13,32,31,21,22,31,32,4, 4,32,4,0,0,4 };//横刀立马//int start[5][4]={31,11,12,4,32,14,13,4,21,22,4,4,31,21,22,31,32,0,0,32};//层拦叠障//int start[5][4]={31,11,12,31,32,14,13,32,4,21,22,4,4,21,22,4,0,21,22,0};//层层设防//int start[5][4]={4,11,12,31,4,14,13,32,21,22,21,22,21,22,21,22,4,0,0,4};//水泄不通//int start[5][4]={4,11,12,4,4,14,13,4,21,22,21,22,21,22,21,22,0,21,22,0};//过五关//int start[5][4]={4,4,4,31,11,12,31,32,14,13,32,31,0,21,22,32,0,4,21,22};//峰回路转//int start[5][4]={31,11,12,4,32,14,13,4,31,31,31,4,32,32,32,4,0,21,22,0};//一路进军//int start[5][4]={4,21,22,4,31,11,12,31,32,14,13,32,4,21,22,4,0,21,22,0};//井中之蛙/*initialize*/for(i=0;i<=4;i++)for(j=0;j<=3;j++)history[0][0][i][j]=start[i][j];print_history(0,0);x=0;y=0;while(1){printf("x=%d width=%d\n",x,width[x]);for(y=0;y<=width[x];y++){t=form_connection();for(p=0;p<t;p++){move(p);if(compare_temp_and_history()==0){write_temp_to_history(x+1,width[x+1]);father[x+1][width[x+1]]=y;width[x+1]+=1;}if(history[x+1][width[x+1]-1][4][1]==14){printf("x=%d width=%d\n",x+1,width[x+1]-1);finisht=clock();for(s=0;s<=x+1;s++) plot_sum+=(width[x]+1);printf("win,耗时:%7f秒展开盘面总数y=%d\n",duration=(double)(finisht-startt)/CLOCKS_PER_SEC,plot_sum);getchar();for(p=x+1,l=width[x+1]-1;p>=0;p--){write_route(p,l);l=father[p][l];}getchar();for(p=0;p<=x+1;p++) {printf("第%d步:\n",p);print_route(p);}return;}}}x++;depth++;}getchar();}int form_connection(){int x1=0,y1=0,x2=0,y2=0;//0的坐标int i,j,p,q,flag=0;branch_num[x][y]=0;//find out the location of 0for(i=0;i<=4;i++)for(j=0;j<=3;j++){if(history[x][y][i][j]==0) {x1=i;y1=j;goto another_zero;}}another_zero:for(i=0;i<=4;i++)for(j=0;j<=3;j++){if(history[x][y][i][j]==0&&(i!=x1||j!=y1)) {x2=i;y2=j;}}//find blocks next to 0,direction to move: up=1,down=3,left=2,right=4if(x1-1>=0) b lock_nearby_single(x1-1,y1,3);if(x1+1<=4) block_nearby_single(x1+1,y1,1);if(y1-1>=0)block_nearby_single(x1,y1-1,4);if(y1+1<=3) block_nearby_single(x1,y1+1,2);if(x2-1>=0) b lock_nearby_single(x2-1,y2,3);if(x2+1<=4) block_nearby_single(x2+1,y2,1);if(y2-1>=0)block_nearby_single(x2,y2-1,4);if(y2+1<=3) block_nearby_single(x2,y2+1,2);//the two zeros nearbyif(abs(x1-x2)+abs(y1-y2)==1) block_nearby_bouble(x1,x2,y1,y2);return(branch_num[x][y]);}void block_nearby_single(int m, int n,int dir){if(history[x][y][m][n]==4) write_block_nearby(4,4,m,m,n,n,dir,0);if(history[x][y][m][n]==31&&dir==1) write_block_nearby(31,32,m,m+1,n,n,dir,0);if(history[x][y][m][n]==32&&dir==3) write_block_nearby(31,32,m-1,m,n,n,dir,0);if(history[x][y][m][n]==21&&dir==2) write_block_nearby(21,22,m,m,n,n+1,dir,0);if(history[x][y][m][n]==22&&dir==4) write_block_nearby(21,22,m,m,n-1,n,dir,0); }void block_nearby_bouble(int x1,int x2,int y1,int y2){int t;if(x1==x2)//横连{if(y1>y2){ t=y1;y1=y2;y2=t;}if(x1+1<=4){ if(history[x][y][x1+1][y1]==21&&history[x][y][x2+1][y2]==22)write_block_nearby(21,22,x1+1,x2+1,y1,y2,1,0);if(history[x][y][x1+1][y1]==11&&history[x][y][x2+1][y2]==12) write_block_nearby(11,12,x1+1,x2+1,y1,y2,1,0);}if(x1-1>=0) {if(history[x][y][x1-1][y1]==21&&history[x][y][x2-1][y2]==22)write_block_nearby(21,22,x1-1,x2-1,y1,y2,3,1);if(history[x][y][x1-1][y1]==14&&history[x][y][x2-1][y2]==13) write_block_nearby(14,13,x1-1,x2-1,y1,y2,3,1);}}if(y1==y2)//纵连{if(x1>x2){ t=x1;x1=x2;x2=t;}if(y1+1<=3){ if(history[x][y][x1][y1+1]==11&&history[x][y][x2][y2+1]==14)write_block_nearby(11,14,x1,x2,y1+1,y2+1,2,0);if(history[x][y][x1][y1+1]==31&&history[x][y][x2][y2+1]==32) write_block_nearby(31,32,x1,x2,y1+1,y2+1,2,0);}if(y1-1>=0) {if(history[x][y][x1][y1-1]==12&&history[x][y][x2][y2-1]==13)write_block_nearby(12,13,x1,x2,y1-1,y2-1,4,0);if(history[x][y][x1][y1-1]==31&&history[x][y][x2][y2-1]==32) write_block_nearby(31,32,x1,x2,y1-1,y2-1,4,0);}}}void write_block_nearby(int a,int b,int x1,int x2,int y1,int y2,int dir,int h) {connection[x][y][branch_num[x][y]][0]=a;connection[x][y][branch_num[x][y]][1]=b;connection[x][y][branch_num[x][y]][2]=x1;connection[x][y][branch_num[x][y]][3]=x2;connection[x][y][branch_num[x][y]][4]=y1;connection[x][y][branch_num[x][y]][5]=y2;connection[x][y][branch_num[x][y]][6]=dir;connection[x][y][branch_num[x][y]][7]=h;branch_num[x][y]++;}void move(int t){int i,j,blk1,blk2,x1,x2,y1,y2,dir,h;for(i=0;i<=4;i++)for(j=0;j<=3;j++) temp[i][j]=history[x][y][i][j];blk1=connection[x][y][t][0];blk2=connection[x][y][t][1];x1=connection[x][y][t][2];x2=connection[x][y][t][3];y1=connection[x][y][t][4];y2=connection[x][y][t][5];dir=connection[x][y][t][6];h=connection[x][y][t][7];//一次只占一个0if(blk1==4){if(dir==1||dir==3) {temp[x1-(2-dir)][y1]=4;temp[x1][y1]=0;}if(dir==2||dir==4) {temp[x1][y1-(3-dir)]=4;temp[x1][y1]=0;}}if(blk1==31&&dir==1){temp[x1-1][y1]=31;temp[x1][y1]=32;temp[x1+1][y1]=0;}if(blk1==31&&dir==3){temp[x2+1][y2]=32;temp[x2][y2]=31;temp[x1][y1]=0;}if(blk1==21&&dir==2){temp[x1][y1-1]=21;temp[x1][y1]=22;temp[x1][y1+1]=0;}if(blk1==21&&dir==4){temp[x2][y2+1]=22;temp[x2][y2]=21;temp[x1][y1]=0;}//一次占用两个0if(blk1==21&&blk2==22&&(dir==1||dir==3)){temp[x1-(2-dir)][y1]=21;temp[x2-(2-dir)][y2]=22;temp[x1][y1] =0;temp[x2][y2]=0;}if(blk1==31&&blk2==32&&(dir==2||dir==4)){temp[x1][y1-(3-dir)]=31;temp[x2][y2-(3-dir)]=32;temp[x1][y1] =0;temp[x2][y2]=0;}if(blk1==11&&blk2==12&&dir==1){temp[x1-1][y1]=11;temp[x2-1][y2]=12;temp[x1][y1]=14;temp[x2][y2]=1 3;temp[x1+1][y1]=0;temp[x2+1][y2]=0;}if(blk1==14&&blk2==13&&dir==3){temp[x1+1][y1]=14;temp[x2+1][y2]=13;temp[x1][y1]=11;temp[x2][y2]=1 2;temp[x1-1][y1]=0;temp[x2-1][y2]=0;}if(blk1==11&&blk2==14&&dir==2){temp[x1][y1-1]=11;temp[x2][y2-1]=14;temp[x1][y1]=12;temp[x2][y2]=1 3;temp[x1][y1+1]=0;temp[x2][y2+1]=0;}if(blk1==12&&blk2==13&&dir==4){temp[x1][y1+1]=12;temp[x2][y2+1]=13;temp[x1][y1]=11;temp[x2][y2]=1 4;temp[x1][y1-1]=0;temp[x2][y2-1]=0;}}void print_history(int p,int q){int i,j;for(i=0;i<=4;i++){for(j=0;j<=3;j++) printf("%2d ", history[p][q][i][j]);printf("\n");}printf("\n");}void print_connection(int p,int q){int i,j;printf(" value x1 x2 y1 y1 dir h\n");for(i=0;i<8;i++){for(j=0;j<8;j++) printf("%2d ", connection[p][q][i][j]);printf("\n");}printf("\n");}int compare_temp_and_history(){int i,j,n,m,flag=0;for(m=0;m<=x+1;m++)for(n=0;n<=width[m];n++){for(i=0,flag=0;i<=4;i++)for(j=0;j<=3;j++){if(temp[i][j]!=history[m][n][i][j]) {i=5;j=4;}else flag++;}if(flag==20) return (1);}return(0);//same}void write_temp_to_history(int x1,int y1){int i,j;for(i=0;i<=4;i++)for(j=0;j<=3;j++) history[x1][y1][i][j]=temp[i][j];}void write_route(int p,int q){int i,j;for(i=0;i<=4;i++)for(j=0;j<=3;j++) route[p][i][j]=history[p][q][i][j];}void print_route(int p){int i,j;for(i=0;i<=4;i++){for(j=0;j<=3;j++) printf("%2d ", route[p][i][j]);printf("\n");} getchar();}图(4)计算结果图(6)程序得出的“横刀立马”解法的前5步和最后“6”步。