【PTA】递归解决九连环问题

什么是递归

递归(Recursion)是一种编程技术,指的是一个函数在其定义过程中调用自身的现象。递归通常用来解决可以被分解为多个相似的小规模子问题的问题。

递归函数一般由以下几部分组成:

  1. 基准条件:递归结束的条件,也称为终止条件,防止函数无限调用自己。通常是简单情形或最小规模的问题,直接返回结果。

  2. 递归步骤:在函数内部调用自己,将问题逐步缩小,朝着基准条件的方向前进。每次调用递归函数时,都会将问题规模减小(如参数递减或数据量减小),直至达到基准条件。

九连环问题

L2-1【用递归实现】 九连环问题

九连环是一种流传于山西省的传统民间的智力玩具,由九个圆环相连成串,以解开为胜。

题图1.jpg

九连环的九个环,一环扣一环地套在钗上。除了第 1 号环可以随时装上或卸下以外,其它环装上或卸下的条件是:在它的前面仅有紧靠它那一个环在钗上。即:当第 1 ~ i−2 号环都不在钗上,第 i−1 号环在钗上,这时可以装上或卸下第 i 号环。

输入格式

环数 操作(U表示装上, D表示卸下)

输出格式

装上或卸下九连环的操作步骤
每行显示一步操作,具体格式为:
环号: U或D (U表示装上,D表示卸下)

输入样例1
3 U

输出样例1
1: U
2: U
1: D
3: U
1: U

输入样例2
4 D

输出样例2
2: D
1: D
4: D
1: U
2: U
1: D
3: D
1: U
2: D
1: D

九连环问题的递归解决

那么,对于九连环问题,我们用递归的方式解决这类问题,其中手动分析是一个重要的阶段,只有正确的用手算找到其中的规律,才能用机器代码的方式表述出来

 九连环的游戏规则:
(1)第 1 环可以自由上下;
(2)而上/下第 n 环时(n>1),则必须满足:(a)第 n-1 个环在架上;(b)前 n-2 个环全部在架下。

为了更好地理解,我们可以通过一个稍微复杂的例子来分析装第 5 号环的过程。

要上第5环,第4环必须在前面,且321都不能在上面

所以,要上前5环,需要分为这四个步骤

 

前四环上去,前三环下来,这样才能把第五环装上,再把前三环上来

对于这四个步骤,还能继续分,

前四个上去可以拆分成,前三个上去,前两个下来,第四个上去,前两个上来

不要怕麻烦,跟着我的文字描述自己写一遍你就会了,总结就是:我们要完成前 5 个环的上环操作,可以分成以下几个步骤:

  1. 上前四环:首先上前四个环。
  2. 下前三环:然后将前三个环卸下。
  3. 装上第 5 个环
  4. 将前三环重新装上

这样,我们就把一个大问题拆解成了若干小问题,类似“爬楼梯”一样,逐步接近目标。✧(≖ ◡ ≖✿)

对于下环来说,除了最后两步需要单独描述,其余的步骤都是有规律的,所以我们把最后两步当作我们的递归出口

 我们再用机器能看懂的语言来描述一下“下环”这个函数

void D(int n){
	if(n>2){
		D(n-2);
		cout<<n<<": "<<"D"<<endl;
		U(n-2);
		D(n-1);
	}
	if(n==2){
		cout<<2<<": "<<"D"<<endl;
		cout<<1<<": "<<"D"<<endl;
	}
	if(n==1){
		cout<<1<<": "<<"D"<<endl;
	}
	
}

那么上环也是同样的,大家手写一遍就明白了,代码如下

void U(int n){
	if(n>2){
		U(n-1);
		D(n-2);
		cout<<n<<" "<<"U"<<endl;
		U(n-2);
	}
	if(n==2){
		cout<<1<<" "<<"U"<<endl;
		cout<<2<<" "<<"U"<<endl;
	}
	if(n==1){
		cout<<1<<" "<<"U"<<endl;
	}
}

递归解题的要点

  1. 找出规律:每个步骤按照规则递归地调用自身。
  2. 设定出口:当问题简化到最小规模(例如 n==1n==2)时,直接输出,不再递归。

运行结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值