现在的位置: 首页 > 综合 > 正文

经典问题-汉诺塔(hanoi)

2013年08月20日 ⁄ 综合 ⁄ 共 1354字 ⁄ 字号 评论关闭

我认为如果一个人是为了学习知识而学习知识,那么就算做题没有别人做的多,牛,那么他也是成功的。因为他学知识始终是为了丰富自己的大脑,让自己成为一个更合格的人。


这个知识点,我做题真的不少了,都是关于汉诺塔的问题,但一次也没有真真正正的去想过这个问题,这是个很好的问题,很古老的问题,期间也有很多传说,比如说,在一个印度的古庙里面,有一个汉诺塔的模型,在其中一跟针上,串了64个金片,要求每天只能按要求移动一个金片,当所有的金片都移动到了另外一根针上的时候,世界将不复存在,我们可以证明,移动的次数为2^64 - 1 = 18446744073709551615,那么相当于 50539024859478223.6年
= 2^64 - 1 / 365,也就是5亿亿年,太阳系的寿命也就才100一年,等你移动完这个塔,宇宙都毁灭了。还有个传说,就是国王要奖赏一个国际象棋的发明人,发明人说,我象棋格子一共64个,您每次在我格子放前一个格子的二倍的大米就行了,国王一天,这个好满足。 18446744073709551615多粒大米好满足?我不想说什么了。


都是随便看看玩玩。言归正传,汉诺塔是一个经典的递归问题,也就是将以一个大问题转化成一个个待解决的小问题。

比如,如果是只有一个盘子,你肯定知道怎么样把盘子从A移动到C,就直接移呗!

再比如,如果是两个盘子,你肯定依然会做,也很简单,先A移动到B,然后A移动到C,然后B移动到C,就完成。

但是,3个呢?有点不好解决,那么,我们首先先设置一个函数,hanoi(n, a, b, c),代表着我现在又N个盘子,我现在要从A借助B移动到C,

那么,利用这个函数表述一下三个的情况是不是就很简单了呢。首先将n-1个借助C先移动到B晒着,即hanoi(n-1,A,C,B),然后将剩下的最后一个直接从A移动到C,好了将最大的先移动到C,就没有什么后顾之忧了,剩下的问题是将在B的那一坨怎么样移动到C上去呢???当然是仍然利用这个函数了,即hanoi(n - 1,B,A,C)那这不就完成了么?你会想那N-1一个怎么移动的呀,那我告诉你,N-1个也是一坨,咱们开始假设的3其实不也是一坨么?3这一坨都解决了,N-1,不也按照这方法解决了就是了么?这就是递归的好处,我只要知道一个解决方法,后面的统统不管,都是这个方法!


贴出代码,完全是根据思想编出来的:

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <string>

using namespace std;
/*
 *经典的汉诺塔问题。
 *A柱借助B移到C上
 */ 

int step;

void move(char a, char c)
{
	printf("step %d: %c --> %c\n", step++, a, c);
}


void hanoi(int n, char a = 'A', char b = 'B', char c = 'C')
{
	if (n == 1)
	{
		move(a, c);
	}
	else
	{
		hanoi(n - 1, a, c, b);
		move(a, c);
		hanoi(n - 1, b, a, c);
	}
}

int main()
{
	int N;
	while (scanf("%d", &N) != EOF)
	{
		step = 1;
		hanoi(N);
	}
	system("pause");
	return 0;
}

抱歉!评论已关闭.