题目描述
汉诺塔是一个古老的数学问题
有三根杆子A,B,C。A 杆上有 n 个 (n>1)穿孔圆盘,盘的尺寸由下到上依次变小。
要求按下列规则将所有圆盘移至 C 杆:
- 每次只能移动一个圆盘;
- 大盘不能叠在小盘上面。
提示:
可将圆盘临时置于 B 杆,也可将从 A 杆移出的圆盘重新移回A杆,但都必须遵循上述两条规则。
问:如何移?最少要移动多少次?
输入描述
一行,包含2个正整数,一个是N,表示要移动的盘了数;一个是M,表示最少移动步数的第M步。
输出描述
共2行。
第一行输出格式为:#No:a->b,表示第M步骤具体移动方法,其中No表示第M步移动的盘子的编号(N个盘子从上到下依次编号为1到n),表示第M步是将No号盘子从a杆移动到b杆(a和b的取值均为(A,B、C])。
第2行输出一个整数,表示最少移动步数。
输入输出样例
输入:
3 2
输出:
#2: A->B
7
最终代码
1. c/c++ 【递归】
#include<bits/stdc++.h>
using namespace std;
int sum = 0, m;
void hanoi(char x,char y,char z,int n)
{
//m是第几步,n是盘子数
if(n==1)
{
sum++;
if(sum==m) cout<<"#"<<n<<": "<<x<<"->"<<z<<endl;
}
else
{
hanoi(x,z,y,n-1);
sum++;
if(sum==m) cout<<"#"<<n<<": "<<x<<"->"<<z<<endl;
hanoi(y,x,z,n-1);
}
}
int main()
{
int n;
cin>>n>>m;
hanoi('A','B','C',n);
cout<<sum<<endl;
return 0;
}
1. c/c++ 【栈,不推荐】
#include<bits/stdc++.h>
using namespace std;
const int N = 30;
int sum = 0, m;
struct mystack{
int a[N]; //存放栈元素
int t = -1; //栈顶位置
void push(int x){ a[++t] = x; } //把x送入栈
int top() { return a[t]; } //返回栈顶元素
void pop() { t--; } //弹出栈顶
int empty() { return t==0?1:0;} //返回1表示空
}st[4]; //定义三个柱子,不用st[0]
void move(int x, int y,int n){ //移动圆盘
int element = st[x].top(); //从杆子x上取出顶部的圆盘放到杆子y上
st[x].pop();
st[y].push(element);
sum++;
char a,b; //用于打印
if(x==1) a='A'; if(x==2) a='B'; if(x==3) a='C';
if(y==1) b='A'; if(y==2) b='B'; if(y==3) b='C';
if(sum == m) cout<<"#"<<n<<": "<<a<<"->"<<b<<endl;
}
void hanoi(int n, int x, int y, int z){
if(n==1) move(x,z,n);
else{
hanoi(n-1, x, z, y);
move(x,z,n);
hanoi(n-1, y, x, z);
}
}
int main(){
int n; cin>>n>>m;
for(int i=n;i>=1;i--) //初始状态:在第1个杆子上添加n个圆盘
st[1].push(i);
hanoi(n,1,2,3);
cout<<sum<<endl;
return 0;
}
2. java
3. python