6.栈和递归
本文章基于《计蒜客2019年蓝桥杯算法训练营》整理记录,并由个人对部分内容进行补充说明,仅用于个人学习交流使用。
0.栈的基本使用
#include<iostream>
#include<stack>
using namespace std;
int main(){
stack<int> s;
s.push(1);//进栈
s.push(2);
s.push(3);
s.pop();//出栈
cout<<s.top()<<endl;//获取栈顶//2
if(!s.empty())//判空
cout<<s.size()<<endl;//获取栈元素个数//2
}
1.汉诺塔问题
//汉诺塔问题
#include<iostream>
#include<stack>
using namespace std;
/*问题分解
1.把 n-1 个盘子移动到B
2.把最大的盘子从A移动到C
3.把B上的n-1个盘子移动到C
递归的方法
*/
stack<int> S[3];//三个柱子
void move(int x,int y){
int temp=S[x].top();
S[x].pop();
S[y].push(temp);
cout<<x<<" --> "<<y<<endl;
}
//三个参数(需要移动的柱子,中间柱,目标柱)
void hanoi(int A,int B,int C,int n){
if(n==1){
move(A,C);
return;
}
hanoi(A,C,B,n-1);
move(A,C);
hanoi(B,A,C,n-1);
}
int main() {
int n;
cin>>n;
//初始化
for(int i=n;i>=1;i--){
S[0].push(i);
}
hanoi(0,1,2,n);
while(!S[2].empty()){
cout<<S[2].top()<<" ";
S[2].pop();
}
return 0;
}
/*
输入:
3
输出:
0 --> 2
0 --> 1
2 --> 1
0 --> 2
1 --> 0
1 --> 2
0 --> 2
1 2 3
*/
2.汉诺塔问题2
小明在玩汉诺塔,假设第一根柱子上从上到下放在大小为1~n的盘子,小明每次移动大小为i的盘子时消耗的体力为i,求他移动盘子的步数,和总共消耗的体力。
#include<iostream>
using namespace std;
long long f[65],g[65];
int main(){
int n;
cin>>n;
f[1]=1;
for(int i=2;i<=n;i++){
f[i]=2*f[i-1]+1;
}
g[1]=1;
for(int j=2;j<=n;j++){
g[j]=2*g[j-1]+j;
}
cout<<f[n]<<" "<<g[n];
return 0;
}
/*
输入:
3
输出:
7 11
*/
3.辗转相除法
//辗转相除法___求最大公约数
/*
f(x,y) = f(y,x%y) y>0
x y=0
*/
#include<iostream>
using namespace std;
int f(int x,int y){
if(y==0){
return x;
}else{
return f(y,x%y);
}
}
int main(){
int x,y;
cin>>x>>y;
cout<<f(x,y)<<endl;
return 0;
}