递归
递归:汉诺塔问题
思路:
即用递归重复以上两步操作即可实现题目所要求的操作
#include<stdio.h>
//x为起始塔,y为中转塔,z为目的塔
void han(char x,char y,char z,int n){
if(n==0)return ;
else{
han(x,z,y,n-1);
printf("%c->%d->%c\n",x,n,z);
han(y,x,z,n-1);
}
}
int main(){
int n;
char a,b,c;//a为起始塔b为目的塔c为中转塔
scanf("%d %c %c %c",&n,&a,&b,&c);
han(a,c,b,n);
return 0;
}
非递归
非递归:汉诺塔问题
思路:和递归的方法相比,非递归的方法实际上就是在找规律,总的规律如下:
(可以自己模拟一下)
代码如下:
#include <bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define eps 1e-6
typedef long long ll;
char s[4]={'0','a','b','c'};
stack<int>a[4];
void move(int now,int next){
a[next].push(a[now].top());
printf("%c -> %c\n",s[now],s[next]);
a[now].pop();
}
int main(){
int n;
cin>>n;
for(int i=0;i<n;i++){
a[1].push(n-i);//把盘子从大到小依次入栈
}
if(n&1){//若n为奇数,则杆的排列顺序改为acb(为了最后樏在c杆上)
s[2]='c';
s[3]='b';
}
while(1){
int next;//标记下一个杆
for(int i=1;i<=3;i++){//第一步:找最小的圆盘(1),然后将它移动到下一个杆上
if(!a[i].empty()){
if(a[i].top()==1){
if(i==3) next=1;
else next=i+1;
move(i,next);
break;
}
}
}
if(a[2].size()==n||a[3].size()==n) break;//判断是否完成移动
int s1,s2;//标记剩下两个杆
switch(next){
case 1:{s1=2,s2=3;break;}
case 2:{s1=3,s2=1;break;}
case 3:{s1=1,s2=2;break;}
}
// 第二步
if(a[s1].empty()) move(s2,s1);//若有空杆则移动到空杆
else if(a[s2].empty()) move(s1,s2);
else{//若无空杆则将较小的圆盘移动到较大的圆盘上
if(a[s1].top()<a[s2].top())
move(s1,s2);
else move(s2,s1);
}
}
return 0;
}