汉诺塔

汉诺塔问题

蹲街弑〆低调 提交于 2020-02-03 07:25:49
汉诺塔问题一直是我想解决的问题之一,汉诺塔也是让我感到编程的神奇之处,想了很久也领悟不了里面的奥秘。 附上灯哥教学视频https://www.bilibili.com/video/av9830115?from=search&seid=6226553387047262312 递归写法 public class Main { public void hanoi(int n, char a, char b, char c) { if (n == 1) { System.out.println(a + "->" + c); }else { hanoi(n-1,a,c,b); hanoi(1,a,b,c); hanoi(n-1,b,a,c); } } public static void main(String[] args) { Main m =new Main(); m.hanoi(3, 'a', 'b', 'c'); } } n = N % M + N / M ; 来源: https://www.cnblogs.com/cznczai/p/11149790.html

算法实验-双色汉诺塔

妖精的绣舞 提交于 2020-02-03 07:04:31
实验原理 与纯汉诺塔问题相同 实验步骤 经过奇偶异同分析可知。当出发柱子A为奇数个盘子 时;最上与最下层颜色为红色,过渡柱子C有偶数个盘子,且最 底层为蓝色:最上层位红色,目标B柱子最底层为红色.A柱子 最上层颜色为奇数一(奇数+偶数)=偶数一蓝色,过渡柱子C上 的偶数个盘子.移动时就变成出发柱子,A柱变成过渡柱子且 叠加的第一个盘子为红色,目标柱子叠加的是蓝色。以此类 推。不会出现同色叠加。 同理,当出发柱子A为偶数个盘子时,最上层为红色、最底 。层为蓝色,过度柱子C有奇数个盘子,且最上、最底层为红色,目 标B柱子最底层为蓝色。A柱子最上层颜色为偶数一(奇数+奇数) =偶数一蓝色.过渡柱子C上的奇数个盘子,移动时就变成出发 柱子.A柱变成过度柱子且叠加的第一个盘子为蓝色.目标柱子 叠加的是红色。以此类推.同样不会出现同色叠加的情况。 关键代码 void move ( int a , int b ) { out << "塔" << a << "到塔" << b << endl ; } void hanoi ( int n , int a , int b , int c ) { if ( n > 0 ) { hanoi ( n - 1 , a , c , b ) ; out << "将第" << n << "盘从" ; move ( a , b ) ; hanoi ( n - 1 ,

【acm1996】汉诺塔

一笑奈何 提交于 2020-02-02 08:48:19
***问题: Problem Description n个盘子的汉诺塔问题的最少移动次数是2 n-1,即在移动过程中会产生2 n个系列。由于 发生错移产生的系列就增加了,这种错误是放错了柱子,并不会把大盘放到小盘上,即各柱 子从下往上的大小仍保持如下关系 : n=m+p+q a1>a2>…>am b1>b2>…>bp c1>c2>…>cq 计算所有会产生的系列总数. Input 包含多组数据,首先输入T,表示有T组数据.每个数据一行,是盘子的数 目N<30. Output 对于每组数据,输出移动过程中所有会产生的系列总数。 Sample Input 3 1 3 29 Sample Output 3 27 68630377364883*** 代码: # include <iostream> using namespace std ; int main ( ) { int n ; cin >> n ; while ( n -- ) { int k ; cin >> k ; __int64 a [ 31 ] ; a [ 1 ] = 3 ; for ( int i = 2 ; i <= k ; i ++ ) { a [ i ] = 3 * a [ i - 1 ] ; } cout << a [ k ] << endl ; } return 0 ; } 分析:,通过对1,2

洛谷 P1242 新汉诺塔 dfs递归

寵の児 提交于 2020-02-02 08:13:43
洛谷 P1242 新汉诺塔 dfs递归 90分代码: 优先保证编号较大的到达目标位置,把其他编号较小的盘子都先移到中间柱子上。 # include <iostream> # include <algorithm> # include <stdio.h> # include <cmath> # include <queue> # include <cstring> # include <vector> # include <map> # define MAX 50 # define INF 0x3f3f3f3f typedef long long ll ; using namespace std ; //p1记录原始位置,p2记录目标位置 int n , p1 [ MAX ] , p2 [ MAX ] , ans = 0 ; void dfs ( int id , int pos1 , int pos2 ) { if ( pos1 == pos2 ) { //说明不需要转移 return ; } for ( int i = id - 1 ; i >= 1 ; i -- ) { //把所有比id小的圆盘移到中转柱上 dfs ( i , p1 [ i ] , 6 - pos1 - pos2 ) ; } p1 [ id ] = pos2 ; printf ( "move %d from

Python-递归的经典问题-汉诺塔

*爱你&永不变心* 提交于 2020-02-02 04:46:12
代码片 下面展示一些 内联代码片 。 # -*- coding: utf-8 -*- def move(n, a, b, c): if n<1: return elif n==1: return print(a, '-->', c) move((n-1),a,c,b) move(1,a,b,c) move((n-1),b,a,c) move(2,'A','B','C') A - - > C A - - > B C - - > B A - - > C B - - > A B - - > C A - - > C 来源: CSDN 作者: #FFC0CB 链接: https://blog.csdn.net/weixin_44948387/article/details/104130766

【acm2064】

人走茶凉 提交于 2020-02-02 00:37:54
***问题: Problem Description 约19世纪末,在欧州的商店中出售一种智力玩具,在一块铜板上有三根杆,最左边的杆上自上而下、由小到大顺序串着由64个圆盘构成的塔。目的是将最左边杆上的盘全部移到右边的杆上,条件是一次只能移动一个盘,且不允许大盘放在小盘的上面。 现在我们改变游戏的玩法,不允许直接从最左(右)边移到最右(左)边(每次移动一定是移到中间杆或从中间移出),也不允许大盘放到下盘的上面。 Daisy已经做过原来的汉诺塔问题和汉诺塔II,但碰到这个问题时,她想了很久都不能解决,现在请你帮助她。现在有N个圆盘,她至少多少次移动才能把这些圆盘从最左边移到最右边? Input 包含多组数据,每次输入一个N值(1<=N=35)。 Output 对于每组数据,输出移动最小的次数。 Sample Input 1 3 12 Sample Output 2 26 531440*** 代码: # include <iostream> # include <cmath> using namespace std ; int main ( ) { int n ; while ( scanf ( "%d" , & n ) != EOF ) { __int64 a [ 36 ] ; a [ 1 ] = 2 ; for ( int i = 2 ; i <= n ; i ++ ) { a [

【acm1995】汉诺塔

情到浓时终转凉″ 提交于 2020-02-02 00:26:55
***问题: Problem Description 用1,2,…,n表示n个盘子,称为1号盘,2号盘,…。号数大盘子就大。经典的汉诺塔问 题经常作为一个递归的经典例题存在。可能有人并不知道汉诺塔问题的典故。汉诺塔来源于 印度传说的一个故事,上帝创造世界时作了三根金刚石柱子,在一根柱子上从下往上按大小 顺序摞着64片黄金圆盘。上帝命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱 子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一回只能移动一个圆盘。我们 知道最少需要移动2^64-1次.在移动过程中发现,有的圆盘移动次数多,有的少 。 告之盘 子总数和盘号,计算该盘子的移动次数. Input 包含多组数据,首先输入T,表示有T组数据.每个数据一行,是盘子的数目N(1<=N<=60)和盘 号k(1<=k<=N)。 Output 对于每组数据,输出一个数,到达目标时k号盘需要的最少移动数。 Sample Input 2 60 1 3 1 Sample Output 576460752303423488 4*** 分析: 2.找规律:假设最上方的盘子编号为 1 。 k 1,移动 1 次 ; k 2,1 移动 2次, 2 移动 1 次; k==3,1 移动 4 次; 2 移动 2 次; 3 移动 1 次; 由此,我们猜测在移动过程中,i 号盘子的移动次数是 i-1 号盘子的两倍

汉诺塔

只愿长相守 提交于 2020-02-01 03:47:16
问题描述: 输入一个整数n,表示有n个盘子,起始时在第一个柱子上,从上到下依次是1-n。现在有1,2,3三个柱子,要求将一号柱子的盘子移动到3号盘子。每移动一个盘子(编号为i)需要消耗i点体力。 现在需要求出移动的最少步数以及消耗的最少体力。 例如: 2 3 4 3 7 11 解法一: 纯递归解法 import java . util . LinkedList ; import java . util . Scanner ; public class Main { private static long step ; private static long cost ; public static void move ( int n , LinkedList < Integer > s1 , LinkedList < Integer > s2 , LinkedList < Integer > s3 ) { if ( n == 1 ) { int pop = s1 . pop ( ) ; s3 . push ( pop ) ; step ++ ; cost + = pop ; } else { move ( n - 1 , s1 , s3 , s2 ) ; int pop = s1 . pop ( ) ; s3 . push ( pop ) ; step ++ ; cost + =

基于c#开发的汉诺塔游戏

佐手、 提交于 2020-01-31 07:39:26
编程语言:C# 带音效带自动演示 核心代码 private void Hanoi ( int n1 , char x , char y , char z ) { if ( n1 == 1 ) { MoveDisc ( x , 1 , z ) ; //编号为1的盘子从x到y } else { Hanoi ( n1 - 1 , x , z , y ) ; //n-1个盘子从x经y到z; MoveDisc ( x , n1 , z ) ; //编号为n的盘子从x到z; Hanoi ( n1 - 1 , y , x , z ) ; //n-1个盘子从y经x到z; } } private void MoveDisc ( char x , int n1 , char z ) { int j , t = 0 ; i = i + 1 ; labeloutput . Text + = "\r\n" + i . ToString ( ) . PadLeft ( 2 ) + ":砖块" + n1 . ToString ( ) . PadLeft ( 2 ) + x + "→" + z ; labeloutput . Visible = true ; buttonwatch . Visible = true ; buttonclean . Visible = true ; /

递归高级应用(汉诺塔)

拜拜、爱过 提交于 2020-01-28 02:19:06
一:汉诺塔问题 所有的盘子刚开始都是放在塔座A上,要求将所有的盘子从塔座A移动到塔座C上,每次只能移动一个盘子,任何盘子不能放在比自己小的盘子上. 二:移动子树 把上层的全部看成一个整体–子树 , 每次移动后子树都在减小,最后子树剩下一个,再放到C座即可 三:递归的解决 public class HanNuoTa { public static void main ( String [ ] args ) { moveTower ( 3 , 'A' , 'B' , 'C' ) ; } /* *移动盘子 * 参数; * 1.num: 移动的盘子数量 * 2.a: 塔座A * 3.b: 塔座B * 4.c: 塔座C */ public static void moveTower ( int num , char a , char b , char c ) { if ( num == 1 ) { //只有一个盘子的时候 System . out . println ( "盘子1 从" + a + "移动到" + c ) ; } else { //大于一个盘子的时候 //1.意思是把上面 num-1 个盘子 从 a 移动 到 b(此时 c 作为过度塔) moveTower ( num - 1 , a , c , b ) ; //2.移动最底下那个盘子到c System . out .