蓝桥杯 汉诺塔
题目描述
汉诺塔是一个古老的数学问题: 有三根杆子 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
代码--栈:
#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; }
代码--递归:
#include<bits/stdc++.h> using namespace std; int m,sum=0; void Hanoi(int n,char a,char b,char c); int main(){ char a='A',b='B',c='C'; int n; scanf("%d %d",&n,&m); Hanoi(n,a,b,c); printf("%d",sum); return 0; } void Hanoi(int n,char a,char b,char c){ if(n==1){ sum++; if(sum==m) printf("#%d: %c->%c\n",n,a,c); }else{ Hanoi(n-1,a,c,b); sum++; if(sum==m) printf("#%d: %c->%c\n",n,a,c); Hanoi(n-1,b,a,c); } }
本文来自博客园,作者:弈星,转载请注明原文链接:https://www.cnblogs.com/8023yyl/p/15881056.html