首页 > 编程语言 >Hanoi问题及其相关快速算法

Hanoi问题及其相关快速算法

时间:2024-03-09 20:01:52浏览次数:31  
标签:lc int hanoi s1 move Hanoi 算法 s2 快速

Hanoi问题

抽象

hanoi(n,x,y,z)

step1: hanoi(n-1,x,z,y)

step2:move(x,z)

step3:hanoi(n-1,y,x,z)

递归部分实现代码
    void hanoi(int n, char x, char y, char z){
​	if(n==1){	//	递归出口
​		move(x,z);
​	}
​	else{
​		hanoi(n-1,x,z,y);
​		move(x,z);
​		hanoi(n-1,y,x,z);
​	}
}

实例

	hanoi(3,'a','b','c')
1.保留入栈line5:n=3 x='a' y='b' z='c'
2.调用hanoi(2, 'a','c','b')
3.保留入栈line5:n=2,x='a',y='c',z='b'
4.调用hanoi(1,'a','b','c')
5.n==1,x->z,namely,a->c
6.返回(3)line5,同时(3)释放出栈,现场恢复,执行move(x,z),a->b
此时hanoi(2,'a','c','b')调用仍未结束
7.调用前保留入栈line7:n=2,x='a',y='c',z='b'
8.调用hanoi(1,'c','a','b')   
9.n==1,move(x,z),namely,c->b
此时hanoi(2,'a','c','b')调用结束,(7)释放出栈恢复现场
语句执行完毕,(1)出栈
10.执行下一条语句move(x,z),namely,a->c
11.保留入栈line7:n=3,x='a',y='b',z='c'
12.调用hanoi(2,'b','a','c')
13.保留入栈line5:n=2,x='b',y='a',z='c'
14.调用hanoi(1,'b','c','a')
15.n==1,move(x,z),namely,b->a
16.返回(13)line5,同时(13)释放出栈
17.执行下一条语句move(x,z),namely,b->c
18.保留入栈line7:n=2,x='b',y='a',z='c'
19.调用hanoi(1,'a','b','c')
20.n==1,move(x,z),namely,a->c  
此时hanoi(2,'b','a','c')调用结束,(18)释放出栈恢复现场
语句执行完毕,(11)出栈
18.hanoi(3,'a','b','c')调用结束

递归轨迹


普通hanoi公式

3个柱子 n个盘子 移动步数2^n-1

int:10^9 long long:10^18 超过数量级采用高精度算法

高精度算法:借助数组逐位处理

加法

#include<bits/stdc++.h>
using namespace std;
char s1[505],s2[505];
int a[505],b[505],c[505];
int main(){
	int la.lb,lc;
	scanf("%s",s1);
	scanf("%s",s2);
	//获取长度 
	la=strlen(s1);
	lb=strlen(s2);
	//逆置 方便各位对齐 
	for(int i=0;i<la;i++){
		a[la-i]=s1[i]-'0';
	}
	for(int i=0;i<lb;i++){
		a[lb-i]=s2[i]-'0';
	}
	lc=max(la,lb)+1;
	//高精度加法 
	for(int i=1;i<lc;i++){
		c[i]+=a[i]+b[i];
		c[i+1]=c[i]/10;
		c[i]=c[i]%10; 
	}
	//当长度大于0 若有前导0 则删除 
	if(c[lc]==0&&lc>0) lc--;
	//逆置输出 
	for(int i=lc;i>0;i--){
		cout<<c[i];
	}
	return 0;
}

减法

#include<bits/stdc++.h>
using namespace std;
char s1[10090],s2[10090],s3[10090];
int a[10090],b[10090],c[10090];
int flag;
bool compare(char *s1,char *s2,int u,int v){
	
	if(u!=v) return u>v;
	for(int i=0;i<u;i++){
		if(s1[i]!=s2[i])
			return s1[i]>s2[i];
	}
	return true;
}
int main(){
	int la,lb,lc;
	scanf("%s",s1);
	scanf("%s",s2);
	la=strlen(s1);
	lb=strlen(s2);
	if(!compare(s1,s2,la,lb)){
		flag=1;
		strcpy(s3,s1);
		strcpy(s1,s2);
		strcpy(s2,s3); 
	}
	//需要再次获取以确认大数-小数对应的长度 
	la=strlen(s1);
	lb=strlen(s2);
	//逆置 方便各位对齐 
	for(int i=0;i<la;i++){
		a[la-i]=s1[i]-'0';
	}
	for(int i=0;i<lb;i++){
		b[lb-i]=s2[i]-'0';
	}
	lc=max(la,lb);
	//高精度减法 
	for(int i=1;i<=lc;i++){
		if(a[i]<b[i]){
			a[i+1]--;
			a[i]+=10;
		}
		c[i]=a[i]-b[i]; 
	}
	//相对于加法 此处lc=max(la,lb) 循环删除前导0 
	while(c[lc]==0&&lc>1) lc--;
	if(flag){
		cout<<"-";
	}
	//逆置输出 
	for(int i=lc;i>0;i--){
		cout<<c[i];
	}
	return 0;
}

乘法

#include<bits/stdc++.h>
using namespace std;
char s1[2005],s2[2005];
int a[2005],b[2005],c[2005];
int main(){
	int la,lb,lc;
	scanf("%s",s1);
	scanf("%s",s2);
	la=strlen(s1);
	lb=strlen(s2);
	lc=la+lb;
	//逆置 方便各位对齐 
	for(int i=0;i<la;i++){
		a[la-i]=s1[i]-'0';
	}
	for(int i=0;i<lb;i++){
		b[lb-i]=s2[i]-'0';
	}
	//高精度乘法 
	for(int i=1;i<=la;i++){
		for(int j=1;j<=lb;j++){
			c[i+j-1]+=a[i]*b[j];
			c[i+j]+=c[i+j-1]/10;
			c[i+j-1]%=10;
		}
	}
	//循环删除前导0 lc>1 namely 0*10=0
	while(c[lc]==0&&lc>1) lc--;
	//逆置输出 
	for(int i=lc;i>0;i--){
		cout<<c[i];
	}
	return 0;
} 

二次幂

#include<bits/stdc++.h>
using namespace std;
int n;
int a[15005];
int main(){
	a[1]=1;
	cin>>n;
	int len=1;
	for(int i=1;i<=n;i++){//a[]*2
		int t=0;
		//高精度乘以一位数 
		for(int j=1;j<=len;j++){
			a[j]=a[j]*2+t;
			t=a[j]/10;
			a[j]%=10;
		}
		//t为进位 只能有一位 
		if(t>0) a[++len]=t;
	}
	for(int i=len;i>=1;i--){
		if(i==1){
			cout<<a[i]-1;
		}
		else{
			cout<<a[i];
		}
	}
	return 0;
} 

快速幂

复杂度:O(log b)

#include<bits/stdc++.h>
using namespace std;
long long a,b,c;
int main(){
	cin>>a>>b>>c;
	a%=c;
	long long ans=1;
	while(b){
		// b is odd or even?
		if(b&1){
			ans=(ans*a)%c;
		}
		a=(a*a)%c;
		// b/2 
		b>>=1;	
	}
	cout<<ans<<endl;
	return 0;
} 

标签:lc,int,hanoi,s1,move,Hanoi,算法,s2,快速
From: https://www.cnblogs.com/2ydy05ac/p/18063203

相关文章

  • 基于Harris角点的室内三维全景图拼接算法matlab仿真
    1.算法运行效果图预览   2.算法运行软件版本matlab2022a 3.算法理论概述      在室内三维全景图的构建中,Harris角点检测算法扮演着关键的角色,用于识别场景中的特征点以实现图像间的匹配和对齐。该过程通常包括以下几个步骤:图像获取、角点检测、特征描述、匹......
  • JAVA使用DFA算法过滤敏感词
    代码示例如下:importcn.hutool.core.collection.CollUtil;importcn.hutool.core.util.ReUtil;importcn.hutool.core.util.StrUtil;importcom.google.common.collect.Lists;importcom.google.common.collect.Maps;importjava.util.*;publicclassSensitiveWordUtils......
  • 中考英语首字母快速突破001-2021上海宝山英语二模
    PDF格式公众号回复关键字:ZKSZM001原文Whatislaughter?Laughterisnaturalforpeople.Westarttolaughataboutfourmonthsofage.Westarttolaughevenbeforewestarttospeak!Laughterissocial.Itconnectsuswithotherpeople.Welaughmorewhenw......
  • 算法面试通关40讲 - 栈
    20.有效的括号std::stack<T>的几个方法:top:相当于backpop:相当于pop_backpush:相当于push_backclassSolution{public:staticcharleftOf(charc){switch(c){case')':return'(';case......
  • 代码随想录算法训练营第四十一天|01背包问题, 01背包问题—— 滚动数组,分割等和子集
    01背包问题,你该了解这些! 题目链接:46.携带研究材料(第六期模拟笔试)(kamacoder.com)思路:第一次遇到背包问题,好好记住吧。代码随想录(programmercarl.com)#include<bits/stdc++.h>usingnamespacestd;intmain(){intm,n;cin>>m>>n;vector<int>z(m);vec......
  • 快速排序
    快速排序-V1一、代码实现1.大致思路假如有一个数,这个数组自然有序假如有2个数,我们选第一个数为标准,比它小的数排它前面,比它大排后面,那么这两个数将有序。假如有3个数,我们选第一个数为标准,比它小的数排它前面,比它大排后面。假如有4个数,我们选第一个数为标准,比它小的数排它前......
  • 最短路算法合集
    dijkstra算法思路:1、将所有顶点分为p、q两个集合,p已求出最短路径,q未求出最短路径。2、令源点\(start\)到自己的距离为0,即\(dis[start]=0;\)3、从p集合中找到距离源点最近的点,与之有边\(<u,v,w>\)相连的点v到源点的距离可更新为\(dis[v]=min(dis[v],dis[u]+w)\),不断重复直到q集......
  • 代码随想录算法训练营第四天| 24. 两两交换链表中的节点 19.删除链表的倒数第N个节点
    24.两两交换链表中的节点https://leetcode.cn/problems/swap-nodes-in-pairs/description/publicListNodeswapPairs(ListNodehead){if(head==null||head.next==null)returnhead;ListNoderes=head.next;ListNodepre=newListNod......
  • ACwing 最短路算法
    ACwing最短路算法首先介绍一下各个最短路算法的分类及适用情况注意:SPFA算法在部分情况下会被卡一些特殊数据,当被卡时,换用其他对应的算法;下面依次介绍:朴素版dijkstra算法朴素版dijkstra算法适用于稠密图,所以我们只以稠密图的存图方式去介绍;核心思想:首先我们定义一个集合st......
  • 代码随想录算法训练营day17 | leetcode 110. 平衡二叉树、257. 二叉树的所有路径、404
    目录题目链接:110.平衡二叉树-简单题目链接:257.二叉树的所有路径-简单题目链接:404.左叶子之和-简单题目链接:110.平衡二叉树-简单题目描述:给定一个二叉树,判断它是否是平衡二叉树示例1:输入:root=[3,9,20,null,null,15,7]输出:true示例2:输入:root=[1,2,2,3,3,null,nul......