蓝桥杯 汉诺塔 C++算法提高 HERODING的蓝桥杯之路

资源限制
时间限制:1.0s 内存限制:256.0MB
问题描述
  汉诺塔是一个古老的数学问题:
  有三根杆子A,B,C。A杆上有N个(N>1)穿孔圆盘,盘的尺寸由下到上依次变小。要求按下列规则将所有圆盘移至C杆:
  每次只能移动一个圆盘;
  大盘不能叠在小盘上面。
  提示:可将圆盘临时置于B杆,也可将从A杆移出的圆盘重新移回A杆,但都必须遵循上述两条规则。

问:如何移?最少要移动多少次?
输入格式
  一行,包含2个正整数,一个是N(N<=15),表示要移动的盘子数;一个是M,表示在最少移动d第M步
输出格式
  共2行。
  第一行输出格式为:#No: a->b,表示第M步骤具体移动方法,其中No表示第M步移动的盘子的编号(N个盘子从上到下依次编号为1到n),表示第M步是将No号盘子从a杆移动到b杆(a和b的取值均为{A、B、C})。
  第2行输出一个整数,表示最少移动步数。
样例输入
3 2
样例输出
#2: A->B
7
数据规模和约定
  0<N<20,0<M<=最小移动步数

解题思路:
对于递归的理解,自以为理解的很透彻了,但是遇到的时候又犯混了,百思不得其解,于是查阅别的博客,终于明白了自己的问题,以前自以为理解透彻是因为递归不够复杂,比如树的中序遍历,很简单就是左下、上、右下的递归,因为很容易理解所以往往忽略了最关键的地方,就是把大化小。比如这个中序遍历,我只是想象成一个只有一个根节点,两个子节点的数,其他的情况都不管了,肯定符合这个最小的树遍历的规律。汉诺塔也是同样的道理,你把汉诺塔中的碟子想象成两个碟子,那么思路肯定是把最上面的碟子放到B,把下面的放到C,再把B上的放到C,三个的情况同样如此,把最上面的两个碟子放到B,把最下面的放到C,再把B上的两个碟子放到C,扩展到N个碟子的情况同样适用。所以,递归的关键就是只用考虑最基本的情况,如果最基本的情况都满足了,那么所有的情况也都满足了,只不过多一个递归的步骤而已,所以千万不要想多,把自己绕进去了。当然这道题目还要单独考虑只有一个碟子的情况。
这道题还有一个复杂的地方在于找出指定步骤移动的盘子,观察发现,当移动步骤为指定步骤时,所在递归的n的数值就是指定步骤移动的盘子。
代码如下:

#include<bits/stdc++.h>

using namespace std; 

int sum = 0;

void hanoi(int n, int m, char one, char two, char three)
{
	if(n <= 1){
		sum ++;
		if(sum == m){
		cout << "#" << n << ": " << one << "->" << three << endl;
		}
		return ;		
	}		
	hanoi(n-1, m, one, three, two);//n-1个碟子放到 B上 
	sum ++;
	if(sum == m){
		cout << "#" << n << ": " << one << "->" << three << endl;
	}	
		hanoi(n-1, m, two, one, three);//n-1个碟子放到 C上 
 } 
int main()
{
	int m, n;
	cin >> n >> m;
	hanoi(n, m, 'A', 'B', 'C');
	cout << sum; 
	return 0;
}

猜你喜欢

转载自blog.csdn.net/HERODING23/article/details/106674366
今日推荐