java汉诺塔不可逆向问题!,将A中碟子在A,B,C三个柱子无限来回放的时候,比如某个碟子刚从A放入B,再把这个碟子从B

pennyhardway2022-10-04 11:39:541条回答

java汉诺塔不可逆向问题!,
将A中碟子在A,B,C三个柱子无限来回放的时候,比如某个碟子刚从A放入B,再把这个碟子从B放入A就是逆向,程序如何写才能保证这逆向不发生!
意思就是我如何给这个方向做一个判定!
//从a"=>"b
public class DiGui{
public static void diGui(int n,char a,char t,char b){
if(n==1){
System.out.println(a+" "+n+"=>"+b);
}else{
diGui(n-1,a,b,t);
System.out.println(a+" "+n+"=>"+b);
diGui(n-1,t,a,b);
}
}
public static void main(String[] args){
diGui(2,'a','t','b');
}
}
上面程序很显然System.out.println(a+" "+n+"=>"+b);做了一个指向,那么假设我们不知道这个放法的方向,怎么给这方向下定义呢?言下之意就是a中的盘子乱放,只要符合栈道(大在下,先进后出)!方法不对再返回重新递归!

已提交,审核后显示!提交回复

共1条回复
ll中的普普 共回答了18个问题 | 采纳率94.4%
public class J_Hanoi
{
public static void mb_hanoi(int n, char start, char temp, char end)
{
if (n
1年前

相关推荐

求四根柱子的汉诺塔问题的详细题目描述?
求四根柱子的汉诺塔问题的详细题目描述?
就是说这个问题究竟有什么要求啊?否则不过是三根柱子汉诺塔多一根冗余的柱子罢了.
被爱的那天1年前1
loveit2010 共回答了21个问题 | 采纳率90.5%
如何能够用最短的次数呗呗
汉诺塔,给你任意一种合法状态,你能计算出从当前到把所有的金片移动到第三个针上的最小步数?
汉诺塔,给你任意一种合法状态,你能计算出从当前到把所有的金片移动到第三个针上的最小步数?
已有代码,看不懂,
int hanio(int a,int b,int c,int n,int *result) //a,b,c 分别代表3根针,n是金片数
{
if(n==1)
{
if(result[n-1]==c) return 0;
else return 1;
}
else if(result[n-1]==c) return hanio(a,b,c,n-1,result);
else if(result[n-1]==a) return hanio(a,c,b,n-1,result)+(1r[j];
cout
btfin1年前1
爱上田海之 共回答了17个问题 | 采纳率88.2%
int hanio(int a,int b,int c,int n,int *result) //a,b,c 分别代表3根针,n是金片数
//result是个长度为n的数组,第一位表示最小的金片,第二位表示次小的金片,...最后一位表示最大的数组.
//数组每个位上的值为a或b或c,表示该金片在哪个针上.显然,对于确定的result只有一种合法状态
{
if(n==1)
{
if(result[n-1]==c) return 0;
else return 1;
} //如果只有一个金片,平凡情况
else if(result[n-1]==c) return hanio(a,b,c,n-1,result);
//如果最大的金片在C针即第三根针上,该金片不动,问题转化为将n-1个金片移到C针上
else if(result[n-1]==a) return hanio(a,c,b,n-1,result)+(1r[j];//这里要防止r溢出
cout
java汉诺塔(河内塔)问题.解释一下汉诺塔为3时怎么想
天之北溟1年前1
yanjingwushi 共回答了18个问题 | 采纳率83.3%
你把1,2盘看成一个特殊的盘.所以现在n=2,当n=2时,需先把1盘移动到B塔中,把1-3步一起看,作用即把特殊盘移动至B.
然后把3盘移动至C塔,即第4步.
最后,把特殊盘移动到C塔上,同样把5-7步一起看,达到的效果即把特殊盘移动至C盘,完成!
等于4的时候 ,其实就是把123盘看成特殊盘!同样的道理,因为汉诺塔是递归实现的,明白之后很简单.
汉诺塔移动的次数实在太多,神庙的和尚们决定偷懒.为了虔诚地偷 懒,他们用严格的语言描述了新的规则
汉诺塔移动的次数实在太多,神庙的和尚们决定偷懒.为了虔诚地偷 懒,他们用严格的语言描述了新的规则
1.有三根柱子,编号为0、1、2.初始状态下,0 号柱子从底向上按照从大到小的次序依次放置了n 个金盘.2.每次移动将一根柱子最顶部的一个金盘移动到另一根柱子的最顶部.在整个操作过程中,每根柱子上的最底部的金盘必须是最大的,而其他金盘的顺序可以和大小无关.3.希望通过移动达到的目标状态是,2 号柱子从底向上按照从大到小的次序依次放置这n 个金盘.求分析解决,C代码
mota501年前1
wu120120 共回答了16个问题 | 采纳率100%
n个盘子的汉诺塔,无论旧规则新规则,都要分三步:
0、把(n-1)个盘子移到1号柱
1、把最后一个盘子移到2号柱
2、把(n-1)个盘子移到2号柱
为啥新规则也要遵守这三步呢.首先,前(n-1)个盘子必须都移到别的地方,才能移动最后一个盘子.这(n-1)个盘子的目标显然都不能是0号柱.
能不能是2号柱呢?也不可能,否则无法把最后一个盘子移到2号柱,因为违反“最底部盘子必须最大”的规则.
所以,第0步必须是把(n-1)个盘子移动到1号柱.
在1号柱上,最大的那个盘子必须在底部,但上面的(n-2)个盘子没有限制,这是唯一和旧规则不同的地方.
于是,旧规则里完全递归的问题在这里有点变化.n个盘子的第0步并不是完全对同一问题的递归,而是产生了新的子问题.
定义以下3种汉诺塔问题.这些问题的移动规则都是新规则.
传统汉诺塔:把n个有序的盘子移到另一柱,移动后仍然有序.
汉诺塔变体1:把n个有序的盘子移到另一柱,移动后最大的盘子必须在最低,但其余盘子随意.
汉诺塔变体2:把n个无序(最大的盘子必须在最低,但其余盘子随意)的盘子移到另一柱,移动后变成有序.
于是,在旧规则下,一个传统汉诺塔问题会产生2个少一个盘子的传统汉诺塔问题;而新规则下,一个传统汉诺塔问题会产生1个少一个盘子的汉诺塔变体1(第0步),以及少一个盘子的汉诺塔变体2(第2步).
接下来考虑m个盘子的汉诺塔变体1.要从0号柱移动到2号柱.要完成这个问题,仍然分3步:
0、把(m-1)个盘子移到1号柱
1、把最大的盘子移到2号柱
2、把(m-1)个盘子移到2号柱
为啥仍然分3步,是因为要求最大的盘子必须在2号柱底部.
但是这里的第2步非常简单,只要把每一个盘子依次移动到2号柱就可以了,不用来回倒腾,因为2号柱的底部已经有一个最大的盘子了.于是需要(m-1)次移动,不可能更少了.
那么第0步呢?这又是一个汉诺塔变体1.也就是熟悉的递归.
先等等,第0步的时候有没有可能在1号柱的底部,由于父问题的移动而已经有一个更大的盘子了?如果是这样,那就不用递归了,直接一个个移到1号柱就行了.
回答是没有,汉诺塔变体1如果有父问题,就一定是父问题的第0步,而第0步之前是没有任何移动的,也就不可能在0号柱以外的地方有更大的盘子.
所以不影响结论,汉诺塔变体1的第0步是递归.
汉诺塔变体1解决之后,2号柱上除了最大的盘子以外,其余盘子的顺序跟少一个盘子的子问题的顺序相反.想象一下第2步的具体过程就能明白了.直觉告诉我这个顺序可能很重要,因为汉诺塔变体2的解法可能跟初始顺序有关.
现在终于可以计算汉诺塔变体1的最优解移动次数了.记m个盘子的汉诺塔变体1的最优解移动次数为H1(m),则H1(m) = H1(m-1) + 1 + (m-1).显然H1(1) = 1,于是H1(m) = 1+2+3+...+m = m(m+1)/2.
接下来考虑m个盘子的汉诺塔变体1按照最优解解决后,2号柱是什么样子?
把所有盘子编号0,1,2,...,m-1.0号最小.
对于1个盘子的汉诺塔变体1,显然最终顺序是0.
对于2个盘子,会把0反序后下面放个1,于是最终顺序是(从顶到底)0,1.
对于3个盘子,会把0,1反序后下面放个2,于是1,0,2.
对于4个盘子,2,0,1,3.
5个盘子,3,1,0,2,4.
6个盘子,4,2,0,1,3,5.
能看出规律了我就不往下写了.最小的盘子竟然是夹在中间……好像不太好搞……
接下来考虑m个盘子的汉诺塔变体2,还是从0号柱移到2号柱.由于在传统汉诺塔中,这个问题是在汉诺塔变体1之后,所以m个盘子的初始排序就是上述的规律.
汉诺塔变体2仍然分3步:
0、把(m-1)个盘子移到1号柱
1、把最大的盘子移到2号柱
2、把(m-1)个盘子移到2号柱
这次,第0步非常简单,因为0号柱上最顶部的盘子恰好就是第二大的,把它移到1号柱之后它就是1号柱的最大盘子.然后把剩下(m-2)个盘子依次移到1号柱顶上就行了,一共是(m-1)次移动.而且移动完后,1号柱上恰好就是(m-1)个盘子的汉诺塔变体1的最终结果.
而第2步移动完后所有盘子需要有序,这也产生了完全一样只是少一个盘子的子问题,形成递归.这个递归比较显然,因为子问题和当前的汉诺塔变体2完全一样.
这样看来汉诺塔变体2和汉诺塔变体1是完全对称的,于是m个盘子的汉诺塔变体2的最优解的移动次数也是H2(m) = m(m+1)/2.
最后回到n个盘子的传统汉诺塔.
第0步是(n-1)个盘子的汉诺塔变体1,需要n(n-1)/2次移动.
第1步是1次移动.
第2步是(n-1)个盘子的汉诺塔变体2,需要n(n-1)/2次移动.
最后的最后,传统汉诺塔的最优解的移动次数是:
H(n) = n(n-1)/2 + 1 + n(n-1)/2 = n^2 - n + 1.
可比旧规则的指数级次数要好多了,这帮和尚的想法还真不错.
以上完全是我个人的现场推理的结论,尽可能进行了严密的推导但难免有遗漏之处,结论是错的也有可能,仅供参考.
汉诺塔有N个塔身,只有左边第一塔上有上小下大的M个圆盘,移动一次只能是一盘且大盘不能在小盘上.
汉诺塔有N个塔身,只有左边第一塔上有上小下大的M个圆盘,移动一次只能是一盘且大盘不能在小盘上.
从左往右有第n个塔(n
移动一次只能是一盘且大盘不能在小盘上。
这里指的是最少的次数,是一个m,n,M,N的关系式。
正移动,反移动不限。
2楼把a去掉,换成m,M,
sunsunsun51701年前2
nihao1234567 共回答了17个问题 | 采纳率88.2%
(1)将上面(n-1)个从左边移到中间,
(2)将第n个从左边移到右边
(3)将上面(n-1)个从中间移到右边
这样就把移动N个的任务,转化成移动两次(n-1)个和移动一次第N个的任务,而移动(n-1)个需要移动两次(n-20个和移动一次第(n-1)个,移动(n-2)个需要移动两次(n-3)个和移动一次第(n-2)个——如此继续,直到转化为移动一个的情形,根据这个过程,可得递推公式
a1=1
an=2an-1+1(n>1)[(n-1)是下标,(n)也是下标]
汉诺塔问题的算法分析及C++实现
汉诺塔问题的算法分析及C++实现
1.当仅有1个盘子时,把这个盘子从A塔柱移动到C塔柱上
2.当圆盘的个数多于1个时,如下解决:
(1) 先将A塔柱上的(n-1)个圆盘通过C塔柱移动到B塔柱上
(2) 再将A塔柱上的第n个圆盘直接移动到C塔柱上
(3) 最后B塔柱上的(n-1)个圆盘通过A塔柱移动到C塔柱上
该算法对应的代码如下:
void hanoi(int n,char a,char b,char c)
{
if(n==1){
cout
dede991年前1
myheart868 共回答了16个问题 | 采纳率87.5%
hanoi函数的目的是解决汉诺塔的移动序列,它有4个参数:
1.n表示要移动的盘子的个数
2.一开始盘子在哪个柱子上,这个变量叫a,所以可以说,一开始在a柱子上
4.最后盘子要移动到哪个柱子上,这个变量叫c,所以可以说,最后要移动到c柱子上
3.中间用来过渡的柱子.汉诺塔一共3个柱子,用两个是不能完成的,所以还要有一个柱子进行过渡.
首先,如果n等于1,说明就只有一个盘子要从a柱子移动到c柱子,那么直接打印a->c
如果盘子的数量大于1,那就要分开解决.
(1)首先把顶上的n-1个盘子从一开始的a柱子移动到b柱子
递归调用:
第一个参数是要移动的盘子数量,现在需要移动n-1个盘子
第二个参数是从哪里开始移动,现在盘子都在a柱子上,所以是a
第四个参数是移到哪里去,现在要移到b柱子上,所以是b
第三个参数是剩下的那个柱子,也就是c
(2)n-1个盘子移掉以后,a柱子只剩下最后的大盘子,直接移到c柱子,也就是打印a->c
(3)把(1)之后移到b柱子上的n-1个盘子从b移动到c
所以递归调用:
第一个参数是盘子个数,现在只有n-1个了
第二个参数是从哪里开始移,现在盘子都在b柱子上,所以是b
第四个参数是移到哪里去,我们要移到c柱子上,所以是c
第三个参数就是另外的一个柱子,所以是a
简单汉诺塔问题汉诺塔问题是指有3根杆子A、B、C。 B杆上有若干碟子,把所有碟子从B杆移到A杆上,每次只能移动一个碟子,
简单汉诺塔问题
汉诺塔问题是指有3根杆子A、B、C。 B杆上有若干碟子,把所有碟子从B杆移到A杆上,每次只能移动一个碟子,大的碟子不能叠在小的碟子上面,把B杆上的三个碟子全部移到A杆上面,C作为过渡杆使用,最少需要移动几次?为什么是7次而不是5次(三个碟子1,2,3,首先分别把1,2移到C杆再从B把3移到A杆,最后把2,1,移到A杆,不是5次吗
自然相见1年前1
善-美 共回答了14个问题 | 采纳率92.9%
把1,2移到C杆违反了规则:大的碟子2不能叠在小的碟子1上面把1移到A,2移到C,1移到C,3移到A,1移到B,2移到A,1再移到A
编写递归函数实现汉诺塔问题:在移动过程中可以利用B座,要求打印移动的步骤.
编写递归函数实现汉诺塔问题:在移动过程中可以利用B座,要求打印移动的步骤.
汉诺(Hanoi)塔问题:古代有一个梵塔,塔内有三个座A、B、C,A座上有n个盘子,盘子大小不等,大的在下,小的在上.有一个和尚想把这n个盘子从A座移到B座,但每次只能允许移动一个盘子,并且在移动过程中,3个座上的盘子始终保持大盘在下,小盘在上.在移动过程中可以利用B座,要求打印移动的步骤.
老刀不宝1年前1
caojun_6727 共回答了20个问题 | 采纳率90%
#include
#include
#define MaxSize 4
typedef int ElemType;
typedef struct
{
x05ElemType data[MaxSize];
x05int top;char name;
}SqStack;
void InitStack(SqStack * &s,char b) //初始化栈
{
x05s=(SqStack *)malloc(sizeof(SqStack));
x05s->top=-1;s->name=b;
}
void ClearStack(SqStack * &s) //销毁栈
{
x05free(s);
}
void CreateStack(SqStack * &s) //创建栈
{
x05int A[MaxSize],i;
x05for(i=0;itop++;
x05x05s->data[s->top]=A[i];
x05}
}
int Pop(SqStack * &s,ElemType &e) //出栈
{
x05if(s->top==-1)
x05x05return 0;
e=s->data[s->top];x05
x05s->top--;
x05return 1;
}
int Push(SqStack * &s,ElemType e) //进栈
{
x05if(s->top==MaxSize-1)
x05return 0;
x05s->top++;
s->data[s->top]=e;
x05return 1;
}
void DispStack(SqStack *s) //显示栈中元素
{
x05for(int i=s->top;i>=0;i--)
x05x05printf("%d ",s->data[i]);
x05printf("n");
}
void Move(SqStack * &A,SqStack * &B) //将栈A的栈顶元素移动到栈B
{
x05ElemType e;
Pop(A,e);
x05Push(B,e);
}
void Hanoi(int n,SqStack *A,SqStack *B,SqStack * &C) //汉诺塔算法
{char e;
x05if(n==1) {Move(A,C);
x05printf("将第%d个碟子从%c移到%c上n",A->data[A->top+1],A->name,C->name);
x05}
x05else{
x05x05Hanoi(n-1,A,C,B);
x05x05Move(A,C);
x05x05printf("将第%d个碟子从%c移到%c上n",A->data[A->top+1],A->name,C->name);
x05x05Hanoi(n-1,B,A,C);
x05}
}
void main()
{
x05SqStack *A,*B,*C;
x05InitStack(A,'A') ;
x05InitStack(B,'B') ;
x05InitStack(C,'C') ;
x05CreateStack(A);
x05printf("A栈中元素从栈顶到栈底依次为:");
x05DispStack(A);
x05Hanoi(MaxSize,A,B,C);
x05printf("C栈中元素从栈顶到栈底依次为:");
x05DispStack(C);
x05ClearStack(A);
x05ClearStack(B);
ClearStack(C);
}
你以为你会做汉诺塔问题了么?C++加难版汉诺塔等你挑战!
你以为你会做汉诺塔问题了么?C++加难版汉诺塔等你挑战!

Problem Description


想必,前面的汉诺塔对于大家来说,just a piece of cake!


我们来玩一个更高级的汉诺塔游戏——双层汉诺塔。双层汉诺塔游戏中,相同大小的盘都有颜色不同的两片,按照次序放在最左边的金刚柱上。
游戏的目的是把不同颜色的盘分别按照上小下大的顺序放在中间和右边的两个柱子上。在移动过程中,在移动过程中,
依旧是遵守大盘必须在小盘之下,而颜色顺序无限制。


下面给出的四个盘子的例子,当然,这个图片是不完整的,还需要把左边粉红色的盘子移到最右边的柱子上,把黄色的盘子移动到中间的柱子上。

Input


第一行输入一个整数t(t < 10),表示测试的组数。
接下来的t行,每行输入一个正偶数n(0


Output


对于每组测试数据,首先输出一行Case #X:,表示第X组测试数据。
接下来,每行都输出移动盘子的步骤,对于每次移动,以"Move from X
to Y"表示,表示需要将X柱子上最顶层的盘子移动到Y柱子上,其中X,Y是A,B,C中的一个,当然,X和Y不可能相同


Sample Input

2
2
4

Sample Output

Case #1:
Move from A to B
Move from A to C
Case #2:
Move from A to C
Move from A to C
Move from A to B
Move from A to B
Move from C to A
Move from C to A
Move from B to C
Move from A to B
Move from A to C


fbiok1年前1
core7600 共回答了13个问题 | 采纳率92.3%
毫无差别啊,只不过一个动作做两次而已,比如原来是move from A to B,现在变成连着两次move from A to B,move from A to B。
数据结构树和二叉树的实际应用不是什么题目,我要就是树二叉树实际应用举例,比如讲递归的实际应用举例是汉诺塔,类似这个.或者
数据结构树和二叉树的实际应用
不是什么题目,我要就是树二叉树实际应用举例,比如讲递归的实际应用举例是汉诺塔,类似这个.
或者换句话说,我要一道题目要用到树和二叉树的,但是又不是抽象的,比如举个例子:下面有两道线性结构的题目:
(1)读入10个整数存入数组a,求数组a中最大的数及位置
(2)小明有10个朋友,小明想知道他们中间谁拥有的玩具数量最多
读入小明10个朋友各有的玩具数目,输出拥有最多玩具数量的人的拥有的玩具数目,及那个小朋友的编号.
我要的是第二题的类型.
学了树和二叉树,最迷糊的是应用在哪里,
为我的分数不被百度吞噬-.-,所以我没弄悬赏分,
lml19871年前1
mcgrandy 共回答了20个问题 | 采纳率95%
一个单位有10个部门,每个部门都有一部电话,但是整个单位只有一根外线,当有电话打过来的时候,由转接员转到内线电话,已知各部门使用外线电话的频率为(次/天)
5 20 10 12 8 4 3 5 6 9
问应该如何设计个内线电话号码,使得接线员拨号次数尽可能少?
这是哈夫曼树的应用