汉诺塔_java_大神勿喷

问题描述

汉诺塔是一个古老的数学问题:
  有三根杆子A,B,C。A杆上有N个(N>1)穿孔圆盘,盘的尺寸由下到上依次变小。要求按下列规则将所有圆盘移至C杆:
  每次只能移动一个圆盘;
  大盘不能叠在小盘上面。

问:n个盘子最少要移动多少次?
输入一个数字n,打印出一个数字表示移动的次数

问题分析

首先将问题从简单到复杂分析,找出规律

设步数为f(n)

当n = 1时,只需要1步,直接将圆盘从A移动到C

当n = 2时,先将1个小圆盘从A移动到B,再将大圆盘从A移动到C,最后将小圆盘从B移动到C,需要3步

当n = 3 时,也可以理解成需要3步,先将2个小圆盘从A移动到B,再将大圆盘从A移动到C,最后将2个小圆盘从B移动到C,由上述可知,移动2个圆盘到指定位置需要3步,因此当n=3时需要 f(3) = 3+1+3=7步

同理,当n = 4时,将问题拆分成3个小圆盘和一个大圆盘的移动,需要 f(4) = 7+1+7=15步


故,f(n) = 2f(n-1)+1
递推得到

圆盘数步数
11
23
37
415
n2f(n-1)+1

有规律便可以求通项公式
f(n) = 2f(n - 1) + 1
f(n) + 1 = 2f(n - 1) + 2
列出关系式
f(n) + 1 = 2(f(n - 1)+1)
f(n - 1) + 1 = 2(f(n - 2)+1)
f(n - 2) + 1 = 2(f(n - 3)+1)

f(3) + 1 = 2(f(2)+1)
f(2) + 1 = 2(f(1)+1)
左右两边分别相乘得
f(n) + 1 = 2(n-1) * (f(1)+1)=2(n-1) * 2 = 2n
故,f(n) = 2n - 1
n个盘子最少要移动2n - 1次

代码实现

1.通项公式法

import java.util.Scanner;

public class HanNuoTa {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		System.out.println((int)Math.pow(2, n) - 1);
	}
}

2.递推法

import java.util.Scanner;

public class HanNuoTa {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		System.out.println(f(n));
	}
	private static int f(int n) {
		if (n == 1) {
			return 1;
		}
		return f(n - 1) + 1 + f(n - 1);
	}
}

3.递归打印步骤

import java.util.Scanner;

public class HanNuoTa {
	static int cut;	//计数器
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		f("A", "B", "C", n);
		System.out.println("将"+n+"个圆盘从A移动到C需要"+cut+"步");
	}
	private static void f(String from, String temp, String to, int n) {
		if (n < 1) {
			return;
		}
		f(from, to, temp, n - 1);	//先将n-1个小圆盘从A移动到B
		cut ++;	//记录移动的步数
		System.out.println(from + " -> " + to);
		f(temp, from, to, n - 1);	//再将将n-1个小圆盘从B移动到C
	}
}

  • 7
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

编程夜游神

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值