该题在蓝桥杯基础数据结构篇,进入后搜索题号1512。
汉诺塔
可以将圆盘临时置于B杆,也可以将A杆移除的圆盘重新移回A杆,但必须遵循上述两条规则。
汉诺塔了解后,题目也了解后,我们先通过试N的个数来找规律:
当N=1时: A—>C; 移动一次
当N=2时: A—>B ; A—>C ; B—>C ; 移动三次
当N=3时:A—>C ; A—>B ; C—>B ; A—>C ; B—>A ; B—>C ; A—>C ; 移动七次
我们可以发现圆盘移动是有规律的:
1.把n-1个圆盘由A移到B;
2.把第n个圆盘由A移到C; -----最大的那个先放到C最底面
3.把n-1个圆盘由B移到C;
我们把n-1个圆盘看成一个整体去分析:
那如何把n-1个圆盘从A移到B呢?(借助C塔移到了B上)
我们可以把n-2个圆盘看成一个整体去分析:
1.把n-2个圆盘由A移到C;
2.把第n-1个圆盘由A移到B; -----这又是最大的,要注意了,这是很明显的递归
3.把n-2个圆盘由C移到B;
那如何把n-1个圆盘从B移到C呢?(借助A塔移到了C上)
1.把n-2个圆盘由B移到A;
2.把第n-1个圆盘由B移到C; -----这还是最大的
3.把n-2个圆盘由A移到C;
接下来是递归写法的代码: ---这里并不是题目的答案,只是汉诺塔的代码
#include<bits/stdc++.h>
using namespace std;
void hanoi(char a,char b,char c,int n){if (n==1) cout<<a<<" -> "<<c<<endl; //直接移动到C柱,输出 else {hanoi(a,c,b,n-1); //把上面n-1个移到B柱cout<<a<<" -> "<<c<<endl; //输出hanoi(b,a,c,n-1); //把剩下n-1个从B柱移到C柱}
}
int main(){int n;cin>>n;hanoi('A','B','C',n);
}
回到题目中来,题目中多了一个最少移动步数的第M步,加个判断条件就行:
1 #include <iostream>
using namespace std;int sum = 0 , m;
void hanoi(char a , char b , char c , int n)
{if(n == 1){sum++;if(sum == m){cout << "#" << n << ":" << " " << a << "->" << c << endl;}}else{hanoi(a , c , b , n-1);sum++;if(sum == m){cout << "#" << n << ":" << " " << a << "->" << c << endl;}hanoi(b , a , c , n-1);}
}
int main()
{// 请在此输入您的代码int n;cin >> n >> m;hanoi('A' , 'B' , 'C' ,n);cout << sum << endl;return 0;
}
C++栈的知识
在C++程序中需要使用栈时,直接用STL stack或者自己编写栈。
手写栈:
因为手写栈非常简单,所以自己编写一个栈并不比用STL stack慢。
1 const int N = 100100; //定义栈的大小2 struct mystack{3 int a[N]; //存放栈元素4 int t = -1; //栈顶位置5 void push(int x){ a[++t] = x; } //入栈6 int top() { return a[t]; } //读栈顶元素,不弹出7 void pop() { t--; } //弹出栈顶元素8 int empty() { return t==0?1:0;} //返回1表示栈为空9 };
STL stack的有关操作如下。
stack<Type> s:定义栈,Type为数据类型,如int、float、char等。
s.push(item) :把item放到栈顶。
s.top():返回栈顶元素,但不将其删除。
s.pop():删除栈顶元素,但不会返回。出栈需要进行两步操作:先获得栈顶元素,再删除栈顶元素。
s.size():返回栈中元素的个数。
s.empty():检查栈是否为空,如果为空则返回True,否则返回False。