noi汉诺塔问题(递归 非递归[栈,思维])

24 篇文章 2 订阅
21 篇文章 2 订阅

汉诺塔问题

递归

递归:汉诺塔问题
在这里插入图片描述
思路:
在这里插入图片描述
即用递归重复以上两步操作即可实现题目所要求的操作

#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;
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值