汉诺塔和大数

大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。
    
    大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上(可以借助第三根柱子做缓冲)。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。

    如图【1.jpg】是现代“山寨”版的该玩具。64个圆盘太多了,所以减为7个,金刚石和黄金都以木头代替了......但道理是相同的。

    据说完成大梵天的命令需要太多的移动次数,以至被认为完成之时就是世界末日!

    你的任务是精确计算出到底需要移动多少次。

    很明显,如果只有2个圆盘,需要移动3次。

    圆盘数为3,则需要移动7次。

    那么64个呢?
    答案:18446744073709551615

    解析:汉诺塔问题有一个规律:如果有n个罗盘,那需要移动2^n-1次。所以说这个题的答案就是2^64-1,问题是怎么算呢?

    Java中有一个大数(BigInteger),BigInteger里面实际上是有一个int类型的数组的,所以说可以存储一个非常大的数。

   代码:

public class 汉诺塔移动次数
{
	public static void main(String[] args)
	{
		BigInteger a = BigInteger.valueOf(2);
		BigInteger b = a.pow(64);    //总共有64个罗盘
		BigInteger c = b.subtract(BigInteger.valueOf(1));
		System.out.println(c);
	}

}

运行结果:

18446744073709551615

由这个带来的联想一:

       若汉诺塔有n个罗盘,那么汉诺塔的移动过程是怎样的?

       思路:若大于1个,则先将n-1个罗盘从第一个柱子通过第三个柱子移动到第二个柱子,然后将第n个罗盘从第一个柱子移动到第三个柱子,最后再将那n-1个罗盘从第二个柱子通过第一个柱子移动到第三个柱子。

 

     代码入下:

import java.math.BigInteger;
import java.util.Scanner;

public class 汉诺塔
{
	
	public static void move(char start,char end)
	{
		System.out.println(start+"-->"+end);   //移动具体步骤
	}
	
	public static void hannuota(int n,char one,char two,char three)
	{
		if(n==1)
		{
			move(one,three);   //将剩下的一个从第一个移动到第三个
		}
		else
		{
			hannuota(n-1,one,three,two);   //将n-1个圆盘从第一个柱子通过第三个移动到第二个
			move(one,three);         //将当前圆盘从第一个移动到第三个
			hannuota(n-1,two,one,three);   //将n-1个圆盘从第二个通过第一个再一移回到第三个
		}
	}

	public static void main(String[] args)
	{
		Scanner in = new Scanner(System.in);
		System.out.print("请输入罗盘的个数:");
		int n = in.nextInt();
		System.out.println("------过程------");
		hannuota(n,'A','B','C');
	}
}

      运行结果:

请输入罗盘的个数:3
------过程------
A-->C
A-->B
C-->B
A-->C
B-->A
B-->C
A-->C
请输入罗盘的个数:4
------过程------
A-->B
A-->C
B-->C
A-->B
C-->A
C-->B
A-->B
A-->C
B-->C
B-->A
C-->A
B-->C
A-->B
A-->C
B-->C

由这个题带来的联想二:

由这个题让我想起了BigInteger的用法用法,这还是我很早之前学习Java时学的,到现在只是隐约记着一些方法,最常用的有如下几个方法:

 先说一下大数的输入方式:

Scanner in = new Scanner(System.in);
BigInteger a = in.nextBigInteger();    //大数的输入
BigInteger b = in.nextBigInteger();
BigInteger c = BigInteger.valueOf(6);  //将int类型的6转换为BigInteger类型的6

大数的加法:d = a + b;

BigInteger d = a.add(b);

大数的减法:d = a - b;

d = a.subtract(b);

大数的乘法:d = a * b;

d = a.multiply(b);

大数的除法:d = a / b;

d = a.divide(b);

大数的取余:对6取余

BigInteger c = BigInteger.valueOf(6);  //将int类型的6转换为BigInteger类型的6
d = a.mod(c);

大数的幂次:例如64次方

d = c.pow(64);        // 例如:6的64次方

具体代码如下:

import java.math.BigInteger;
import java.util.Scanner;

public class 大数
{
	public static void main(String[] args)
	{
		Scanner in = new Scanner(System.in);
		System.out.print("请输入a:");
		BigInteger a = in.nextBigInteger();    //大数的输入
		System.out.print("请输入b:");
		BigInteger b = in.nextBigInteger();  
		BigInteger d = a.add(b);      // a+b
		System.out.println(a+" + "+b+" = "+d);
		d = a.subtract(b);            // a-b
		System.out.println(a+" - "+b+" = "+d);
		d = a.multiply(b);            // a*b
		System.out.println(a+" * "+b+" = "+d);
		d = a.divide(b);              // a/b
		System.out.println(a+" / "+b+" = "+d);
		BigInteger c = BigInteger.valueOf(6);  //将int类型的6转换为BigInteger类型的6
		d = a.mod(c);                // a%b
		System.out.println(a+" % "+c+" = "+d);
		d = c.pow(64);        // 例如:6的64次方
		System.out.println(c+" ^ 64"+" = "+d);

	}

}

运行结果:

请输入a:6465465156131232
请输入b:564565135132132
6465465156131232 + 564565135132132 = 7030030291263364
6465465156131232 - 564565135132132 = 5900900020999100
6465465156131232 * 564565135132132 = 3650176209563319913806251946624
6465465156131232 / 564565135132132 = 11
6465465156131232 % 6 = 0
6 ^ 64 = 63340286662973277706162286946811886609896461828096

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值