A Different Task(新汉诺塔问题)

来源:互联网 发布:mac docker lnmp 编辑:程序博客网 时间:2024/06/10 03:38
\epsfbox{p10795a.eps}

The (Three peg) Tower of Hanoi problem is a popularone in computer science. Briefly the problem isto transfer all the disks frompeg-A to peg-C using peg-B as intermediate one in such away that at no stage a larger disk is above a smaller disk. Normally, we wantthe minimum number of moves required for this task. The problem is used as anideal example for learning recursion. It is so well studied that one can findthe sequence of moves for smaller number of disks such as 3 or 4.A trivial computer program can find the case of large number of disks also.


Here we have made your task little bit difficult bymaking the problem more flexible. Here the disks can be in any peg initially.

\epsfbox{p10795b.eps}

If more than one disk is in a certain peg, then they will be in a valid arrangement (larger disk will not be on smaller ones). We will give you two such arrangements of disks. You willhave to find out the minimum number of moves, which will transform the firstarrangement into the second one. Of course you always have to maintain theconstraint that smaller disks must be upon the larger ones.

Input

Theinput file contains at most 100 test cases. Each test case starts with apositive integerN (1$ \le$N$ \le$60), which means thenumber of disks. You will be given the arrangements in next two lines. Eacharrangement will be represented byN integers, which are1,2or 3. If the i-th (1$ \le$i$ \le$N)integer is 1, you should consider that i-th disk is onPeg-A. Input is terminated byN = 0. This case should not beprocessed.

Output

Outputof each test case should consist of a line starting with `Case #: ' where # is the test case number. It should be followed by the minimum numberof moves as specified in the problem statement.

Sample Input

31 1 12 2 231 2 33 2 141 1 1 11 1 1 10

Sample Output

Case 1: 7Case 2: 3Case 3: 0参考了大刘的思想:    假设要将第k个盘子移动从柱子1移动到柱子2,比编号k大的盘子不用理它,把他们当作空气;比编号k小的盘子既不能放在柱子1上也不能放在柱子2上,因此只能放在柱子3上。换句话说,这时柱子1只有盘子k,柱子2为空,柱子3从上到下一次为盘子1,2,3....,k-1。我们把这个居面叫做参考局面。    由于盘子的移动是可逆的,根据对称性,我们只需要求出初始局面和目标局面移动成参考局面的步数之和,然后加1(移动盘子k)。设有函数fun(P,i,target),表示已知各个盘子的初始柱子编号数组为p,把p[i]移到target所需要的步数。则答案为:fun(start,k-1,6-start[k]-end[k])+fun(end,k-1,6-start[k]-end[k])。我们把柱子编号为1,2,3所以除了x,y之外的柱子为6 - x - y。    当P[i] = target的时候,fun(p,i,target)=fun(p,i-1,target)+1。不相等时,fun(p,i,target)=fun(p,i-1,6-p[i]-target) + 2 ^(i-1)。代码如下:
#include <cstdio>__int64 fun(int *p,int i,int target){if (!i){return 0;}if (p[i] == target){return fun(p,i - 1,target);}return fun(p,i - 1,6 - p[i] - target) + (1L << (i - 1));}int n,start[60],end[60];int main(){int count = 0;while (scanf("%d",&n) == 1 && n){for (int i = 1; i <= n; i++){scanf("%d",&start[i]);}for (int j = 1; j <= n; j++){scanf("%d",&end[j]);}int k = n;while (k >= 1 && start[k] == end[k])//最大编号不需要移动{k--;}__int64 tag = 0;if (k >= 1){int target = 6 - start[k] - end[k];tag = fun(start,k - 1,target) + fun(end,k - 1,target) + 1;}printf("Case %d: %lld\n",++count,tag);}return 0;}

 
原创粉丝点击