描述
汉诺塔问题比较经典,这里修改一下游戏规则:现在限制不能从最左侧的塔直接移动到最右侧,也不能从最右侧直接移动到最左侧,而是必须经过中间。求当塔有n层的时候,打印最优移动过程和最优移动总步数。
输入描述:
输入一个数n,表示塔层数
输出描述:
按样例格式输出最优移动过程和最优移动总步数
示例1
输入:
2
复制
输出:
Move 1 from left to mid
Move 1 from mid to right
Move 2 from left to mid
Move 1 from right to mid
Move 1 from mid to left
Move 2 from mid to right
Move 1 from left to mid
Move 1 from mid to right
It will move 8 steps.
说明:当塔数为两层时,最上层的塔记为1,最下层的塔记为2
思路:
无论多少层,都看作有两层,最底下的一层(X)、上面(N-1)层合并起来的作为一层(Y),目标是将X移动到最右侧,然后再把Y移动到最右侧。
可将以上问题递归分析,即将X移到最右侧,Y移至最左侧,变成Y移至最右侧的子问题
递归的移动方式:
Y从A塔移动到B塔
Y从B塔移动到C塔
X从A塔移动到B塔
Y从C塔移动到B塔
Y从B塔移动到A塔
X从B塔移动到C塔
将Y看做X,继续递归移动
#include<bits/stdc++.h>
using namespace std;
long long ans=0;
char * str[3]={"left","mid","right"};
void Hanoi(int n,int src,int md,int dest){
if(n==0){
return;
}
Hanoi(n-1,src,md,dest); //包含将上方的n-1个元素从左移到中,再从中移到右两步
ans++;
printf("Move %d from %s to %s\n",n,str[src],str[md]);//将最下方元素从左移到中
Hanoi(n-1, dest, md, src); //包含将右侧的n-1个元素从右移到中,再从中移到左两步
ans++;
printf("Move %d from %s to %s\n",n,str[md],str[dest]);//将最下方元素从中移到右
Hanoi(n-1, src, md, dest); //此时变成左侧有n-1个元素的子问题
}
int main(){
int n;
cin>>n;
Hanoi(n,0,1,2);
printf("It will move %lld steps.",ans);
}