题目描述
汉诺塔是一个古老的数学问题: 有三根杆子 A,B,C。A 杆上有 N 个 (N>1) 穿孔圆盘,盘的尺寸由下到上依次变小。要求按下列规则将所有圆盘移至 C 杆:
- 每次只能移动一个圆盘
- 大盘不能叠在小盘上面
提示:可将圆盘临时置于B杆,也可将从A杆移出的圆盘重新移回A杆,但都必须遵循上述两条规则。问:如何移?最少要移动多少次?
输入描述
一行,包含 2 个正整数,一个是 N,表示要移动的盘子数;一个是 M,表示最少移动步数的第 M 步。
输出描述
共 2行。
第一行输出格式为:#No: a->b
,表示第 M 步骤具体移动方法,其中 No 表示第 M 步移动的盘子的编号(N个盘子从上到下依次编号为 11 到 nn),表示第M步是将 No 号盘子从 a 杆移动到 b 杆(a和 b 的取值均为 {A、B、C})。
第 2 行输出一个整数,表示最少移动步数。
样例">样例">样例">样例">样例">输入输出样例
示例 1
输入
3 2
输出
#2: A->B
7
运行限制
这题其实就是分治和递归算法。
思想是:假设有n个圆盘,分为以下三步:
1:将前n-1个圆盘从A放到B
2:将第n个圆盘从A放到C
3:将前n-1个圆盘从B放到C
中间那步是从A放到C,中间以后那一步就是从A借助C移动到B,中间以下那步就是从B借助A移动到C。
这只是大概思路,如果看不懂可以自行搜索汉诺塔相关资料,个人觉得以下这篇文章写得很好。
(55条消息) 汉诺塔 ——递归_Sharing_的博客-CSDN博客
import java.util.*;
public class Main {
static int m,sum=0;//sum原来统计步数
static void hanoi(char a,char b,char c,int n) {
if(n==1) {
sum++;
if(sum==m)
System.out.println("#"+n+": "+a+"->"+c);
}
else {
hanoi(a,c,b,n-1);//这步可以理解为圆盘从A借助C移动到B
sum++;
if(sum==m)
System.out.println("#"+n+": "+a+"->"+c);
hanoi(b,a,c,n-1); //这步可以理解为圆盘从B借助A移动到C
}
}
public static void main(String[] args) {
Scanner in=new Scanner(System.in);
int n=in.nextInt();
m=in.nextInt();
hanoi('A','B','C',n);
System.out.println(sum);
}
}