HDU - 1995 汉诺塔V 难度:递归入门 复杂度:有点复杂

方案一(公式法)

我还不清楚用递归来解汉诺塔问题是怎么解,对递归比较陌生,但后来发现这题可以不用递归,套用下面发现的公式即可。
一个盘  1号1次
两个盘  1号2次    2号1次
三个盘  1号4次    2号2次    3号1次
四个盘  1号8次    2号4次    3号2次    4号1次
五个盘  1号16次  2号8次    3号4次    4号2次    5号1次
......
K个盘  1号2^K-1^次  2号2^K-2^次  ...k号2^K-k^次  ...K号1次
因此这题算法也极其简单,就看能不能找到这个公式了。
要注意的是这里的幂运算函数的返回值可能会超出整型范围,此种情况的解决要视具体题目的结果极限值而定,在这题中把幂函数的返回值类型设为长长整型(long long)即可。
Extra:
舍友说他一眼就看出了这个公式!因为:题目中写道64个盘子,总移动数为2^64^-1次,而
2^n^-1=1(即2^0^)+2^1^+2^2^+2^3^+...+2^n-1^
所以等式右边从左往右各项依次是n号盘,n-1号盘,n-2号盘,...,2号盘,1号盘的移动次数,所以有n个盘子时的k号盘移动次数为2^n-k^

#include<iostream>
using namespace std;
long long mi(int x, int n)//幂运算函数
{
	long long res = 1;
	for (int i = 0; i < n; i++)
		res *= x;
	return res;
}
int main()
{
	int T;
	cin >> T;
	int* K = new int[T+1];
	int* k = new int[T+1];
	for (int i = 0; i < T; i++)
		cin >> K[i] >> k[i];
	for (int i = 0; i < T; i++)
		cout << mi(2, K[i] - k[i]) << endl;
	return 0;
}

思路方案二(递归)

~(在想明白汉诺塔I的递归思路之后,结合师兄给的该题递归题解经过反复思索,终于把这个汉诺塔V的递归也啃了下来。也许想明白之前很难想明白,但明白之后往往就觉得不难了。所以耐心坚持很重要)~ 设三个柱分别为左中右,左是起始柱,中间是额外柱,右是目标柱。 假设总共要把K个盘从左移到右时,第k号盘需要FUN(K,k)步。 当K=k时,第k个盘子就是最底下的盘子,只需1步,所以K=k时FUN(K,k)必等于1; 否则(K肯定大于k,即K-1>=k),按以下步骤操作:

  • 先把上面K-1个盘从左移到中间,第k号盘需要FUN(K-1,k)步
  • 再把最后一个盘从左移到右,这时第k号盘不需要移动,因此不计步
  • 把中间K-1个盘从中间移到右,第k号盘需要FUN(K-1,k)步 即当K>k时第k号盘需要2*FUN(K-1,k)步。

在代码中我将这里的FUN函数取名为move,注意返回值类型需要为long long。

#include<iostream>//B递归法
using namespace std;
long long int move(int K, int k)
{
	if (k == K)
		return 1;
	else
		return 2 * move(K - 1, k);
}
int main()
{
	int T;
	cin >> T;
	int* K = new int[T + 1];
	int* k = new int[T + 1];
	for (int i = 0; i < T; i++)
		cin >> K[i] >> k[i];
	for (int i = 0; i < T; i++)
		cout << move(K[i], k[i]) << endl;
	return 0;
}

转载于:https://my.oschina.net/u/4035395/blog/3011209

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值