谭浩强C++课后习题12——汉诺塔问题

谭浩强C++课后习题12——汉诺塔问题

问题描述:汉诺塔问题,这是一个经典的数学问题:古代有一个梵塔,塔内有3个座A,B,C,开始时A座上有64个盘子,盘子大小不等,大的在下,小的在上。有一个老和尚想把这64个盘子从A座移到C座,但每次只允许移动一个盘子,且在移动的过程中再3个座上都始终保持大盘在下小盘在上,在移动的过程中可以利用B座,要求编程序打印出移动的步骤。
在这里插入图片描述
算法思路:这是一个典型的递归问题,如果盘子的数量少,一般人是可以直接想出移动盘子的具体步骤的,但是如果盘子的数量很多,移动的步骤就很多。要把64个盘子从A通过B移动到C,想出每一个步骤是非常困难的,不妨一层一层去思考,如果要把64个盘子从A移动到C,如果先把上面的63个盘子通过C移动到B,再把最后一个盘子移动到C,再把那63个盘子通过A移动到C问题就解决了,又回到之前的问题,如何把那63个盘子从A通过C移动到B呢?又如何把63个盘子从B通过A移动到C呢?其实解决的方法就和之前一样了,再进行一次递归。如此层层下放,而递归结束的条件就是最后只需要移动一个盘子。
由上面的分析可知:将n个盘子从A移动到C可以分解为以下3个步骤:
(1)将A上的n-1个盘子借助C先移动到B座上。
(2)把A座上剩下的一个盘子移动到C座上。
(3)把n-1个盘子从B座借助于A座移动到C座上。
上面的(1)步和(3)步都是把n-1个盘子从一个座移动到另一个座上,采取的办法是一样的,只是座的名字不同。为使之一般化,可以将(1)和(3)步表示为:将one座n-1个盘子移动到two座上,只是one,two,three和A,B,C的对应关系不同。
用move函数模拟盘子的移动过程,将其输出。

#include<iostream>
using namespace std;
void move(char a, char b) {
	cout << a << "-->" << b << endl;
}
void Hanoi(int n, char one, char two, char three) {
	if (n == 1) {
		move(one, three);
	}
	else {
		Hanoi(n - 1, one, three, two);
		move(one, three);
		Hanoi(n - 1, two, one, three);
	}
}
int main() {
	int n;
	cout << "输入盘子数:";
	cin >> n;
	Hanoi(n, 'A', 'B', 'C');
	return 0;
}

运行测试结果:(以4个盘为例)
在这里插入图片描述

发布了35 篇原创文章 · 获赞 35 · 访问量 614

猜你喜欢

转载自blog.csdn.net/weixin_45295612/article/details/105220310