【问题】
“上上下下左右左右 BABA”这一连串操作往往能勾起许 MSTCer 的回忆,当年的插卡游戏机(红白机),有一款魂斗罗游戏 ,一个战士或两个战士打通关。一般只有 3 条命,但是在开始前在游戏柄上操作按这个顺序操作按键,就可以调 30 个命。说起红白机,手柄是必不可少的,MSTCer都是爱思考的同学,他们在想,能否用手柄上这些按键就完成数字输入呢?例如给定一个数字 678654 或者 520131 等,然后使用手柄在输入区输入这个数字,答案是肯定的,方案有很多种,但是为了体现我们 MSTCer 的聪明、独特之处,于是大家就想出了以下这种输入方案:
“上上下下左右左右 BABA”中,上用↑表示,下用↓表示,左用←表示,右用→表示。先定义一个输入区,模拟 6 位数的输入,输入区有六个位置为(从左到右)第 1 位,第 2 位,第 3 位,第 4 位,第 5 位,第 6 位。有一个指针指向当前操作位置,称其为指针,手柄上的六个按键分别执行以下操作:
↑:按↑,指针所指向的位置不变,将指针指向位置的数字加 1(除非它是 9)。例如,如果指针指向的数字为 6,按↑之后,该数字变为 7;如果该数字是 9,则按↑之后,数字以及指针位置都不变;
↓:按↓,指针所指向的位置不变,将指针指向位置的数字减 1(除非它是 0),如果该处数字为 0,则按↓之后,数字不变,指针所指位置也不变;
←:按←,指针向左移一个位置,如果指针已经指向输入区的第 1 位,则指针位置不变化;
→:按→,指针向右移一个位置,如果指针已经指向输入区的第 6 位,则指针位置也无变化。
A:按 A,指针所指位置不变,输入区第 1 位的数字会和指针所指位置的数字交换。如果指针指向的是第 1 位,则按 A 键之后,输入区无变化;
B:按 B,指针所指位置不变,输入区第 6 位的数字会和指针所指向的数字与交换。如果指针指向的是第 6 位数字,则按 B 键之后,输入区无变化;
因为不能直接输入数字,为了能够达到输入数字的目的,每次输入目标数字之前,输入区总会先随机生成一个 6 位数字,指针在1-6中随机给定。当灵活运用手柄上的这六个键,就可以得到目标数字,完成输入,最终允许指针指向任何位置。
可以看出,使用这种方案,输入同一个目标数字可能有不种操作方式(按键次数不一),但是存在一种输入方案,使得需要按键次数最少。现在请你编写一个程序,求出输入一个目标数字需要的最少按键次数是多少。
【输入】
每次的输入样例由三行组成,第一行表示随机产生的初始值。第二行表示随机产生的指针值n(1≤n≤6)。第三行表示给定的六位目标数字。
【输出】
对于每一次输出样例,输出达到目标数字的最少按键次数。每一次输出样例另起一行。
【示例输入】
123456
1
654321
【示例输出】
11
-------------------------------------------------------------------------------------------------------------------------------------------------------
【解答】
本题示例代码中提供了两种解法,一种基于宽度优先搜索,另外一种基于深度优先搜索。当然在求步骤最小这一系列问题中,宽度优先搜索更有优势。在这里为了给大家举个例子,也顾不了那么多了。
在示例代码中,为了成功运行深度优先搜索。主要添加了两种剪枝:一种是强制的,不一定正确的,强制限制搜索深度在15以内(如果最短步骤大于15,深度优先搜索不能找到正确解;如果将这项剪枝出掉,系统会出现内存分配失败异常)。第二种剪枝是:在之前搜索