题目大意:汉诺塔,输入n个盘子的初始位置和最终位置,求从初始状态到最终状态所需移动的步数!
题目分析:
考虑盘子的初始状态start和目标状态final,我们只需找到两种状态中位置不相同的编号最大的盘子k,因为编号大且位置相同,则根本不需要要移动。则移动移动盘子k到目标状态final时,其他小于k的k-1个盘子一定顺序堆叠在6-final-start柱子上(将三根柱子依次编号1,2,3);设此时状态为参考状态,则将初始状态移成目标状态等同于,将目标状态和初始状态分别移至参考状态的步数之和+1;因为汉诺塔的移动是可逆的。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX 70
#define LL long long
int n;
int start[MAX],end[MAX];
LL f(int *p,int i,int final)
{
if (i==0)
return 0;
if (p[i]==final)
{
return f(p,i-1,final);
}
return f(p,i-1,6-p[i]-final)+(1LL<<(i-1));
}
int main()
{
int cnt=1;
while (scanf("%d",&n)!=EOF)
{
if (n==0)
break;
int i,j;
for (i=1;i<=n;i++)
{
scanf("%d",&start[i]);
}
for (i=1;i<=n;i++)
{
scanf("%d",&end[i]);
}
LL ans=0;
int k=n;
while (k>=1&&start[k]==end[k])
{
k--;
}
if (k>=1)
{
int other=6-end[k]-start[k];
ans=f(start,k-1,other)+f(end,k-1,other)+1;
}
printf("Case %d: %lld\n",cnt++,ans);
}
return 0;
}