汉诺塔

[SHOI2008]汉诺塔

回眸只為那壹抹淺笑 提交于 2019-11-29 00:43:42
题意 规则同汉诺塔,强制规定移动操作的优先级,每次选择合法的优先级最高的操作,两次操作不能移动同一个盘子,保证有解,求移动次数 思路 将普通汉诺塔问题的思路用在这道题上面,容易证明 \(f\) 满足线性递推关系: \(f[i]=k*f[i-1]+b\) ,暴力 \(dfs\) 出前三个 \(f\) ,就可以求出 \(k=\frac{f[3]-f[2]}{f[2]-f[1]},b=f[2]-f[1]*k\) Code #include<bits/stdc++.h> #define N 35 using namespace std; typedef long long ll; int n; char a[7][3]; ll f[N],k,b; int st[4][4],top[4]; template <class T> void read(T &x) { char c;int sign=1; while((c=getchar())>'9'||c<'0') if(c=='-') sign=-1; x=c-48; while((c=getchar())>='0'&&c<='9') x=x*10+c-48; x*=sign; } void dfs(int step,int opt,int las) { if(top[2]==opt||top[3]==opt) {f[opt]=step;

汉诺塔问题(分治递归思想)

生来就可爱ヽ(ⅴ<●) 提交于 2019-11-28 23:02:27
汉诺塔的基本思想就是 1.先把上面n-1个通过c转移到b(因为我的c里面要放n,也就是最大的那个) 2.把a中的 n(最大的那个)移动到c 3.再把b中的n-1个通过a移动到c; 整个过程就结束了,然后递归调用这个函数,每一层递归都执行这三个步骤 最后n=1的时候,想象一下,n=1的时候,是不是把c中的1直接移到c中即可,所以这就是终止条件。今天可算是理解了汉诺塔的原理了!!!` `` #include using namespace std; void movef(int n,char a,char b){ cout<<“把”<<n<<“从”<<a<<“移动到”<<b<<endl; } void haniod(int n,char a,char b,char c){ if(n==1){ movef(n,a,c); }else{ haniod(n-1,a,c,b); movef(n,a,c); haniod(n-1,b,a,c); } } int main(){ int n; cin>>n; haniod(n,‘a’,‘b’,‘c’); } 来源: https://blog.csdn.net/qq_43568790/article/details/100147676

汉诺塔

試著忘記壹切 提交于 2019-11-28 08:58:55
''' 问题: 有三个柱子A、B、C。移动n个盘子从 A -> C 分析: 步骤1: 移动前n-1个盘子 A -> B 步骤2: 移动第n个盘子 A -> C 步骤3: 移动前n-1个盘子 B -> C 实验: (n个盘子从上到下编号:1, 2, 3,...,n) n=2: move 1 A -> B 步骤1:移动前n-1个盘子 A -> B move 2 A -> C 步骤2:移动第n个盘子到 A -> C move 1 B -> C 步骤3:移动前n-1个盘子 B -> C n=3: move 1 A -> C move 2 A -> B move 1 C -> B 移动前n-1个盘子 A -> B move 3 A -> C 移动第n个盘子到 A -> C move 1 B -> A move 2 B -> C move 1 A -> C 移动前n-1个盘子 B -> C n=4: 4 A C 3 A B 4 C B 2 A C 4 B A 3 B C 4 A C 可以看到, 要把盘子A->B 要通过C, 把盘子从B->C要通过A def move(n, start,end, middle) move n start -> middle move n-1 start -> end move n middle-> end if n==1: move 1 A -> C move

汉诺塔问题详解

徘徊边缘 提交于 2019-11-28 05:56:29
【问题背景】 A柱子上有a个从上到下半径依次递减的圆盘。 A是初始柱子 B是空柱子 C也是空柱子 你要求把A上的a个圆盘都放到C柱子上去 并且C柱子上最后的圆盘的次序也同初始的A柱子一样 在移动盘子的过程中,不能将大盘子放在小盘子上面 一次只能移动一个圆盘 【详解】 这个问题可以分为三个步骤: 1.将A柱子上上面的a-1个圆盘全都移动到B柱子上. 2.把A柱子上唯一的一个圆盘移动到C柱子上。 3.把B柱子上的a-1个圆盘全都移动到C柱子上。 需要注意的是,第1步和第3步实际上都是递归进行的。 我们先来看第1个步骤。 把A柱子上面的a-1个圆盘移动到B柱子上。 这个时候,我们会发现这是原问题的一个缩小版,都是3个柱子,只不过第一个柱子上你现在 只需要考虑最上面的a-1个圆盘了。然后条件还是一样,B,C柱子是空的,让你把这a-1个圆盘放到 [B]柱子上去(对!目标的柱子改了!) 但他本质上还是同一个问题,所以我们可以写出这么一个递归程序了 (a,b,c表示A,B,C柱子上每个柱子的圆盘个数) void solve(char A,char B,char C,int a,int b,int c){   if (a==0){     说明没有任何圆盘要移动,直接return;   }   solve(A,C,B,a-1,c,b);//把A柱子上的a-1个盘子全都移动到B柱子上去

Python实现的一些常见简单问题(持续更新)

冷暖自知 提交于 2019-11-28 05:31:57
提纲: 1.汉诺塔 2.找到某个范围内的所有质数 3.杨辉三角 4.用闭包实现一个计数器,调用一次计数器加1 5.将类构造成可迭代对象,实现斐波那契数列 ...... 1.汉诺塔( 汉诺塔 ) 用递归函数实现汉诺塔(A、B、C柱,要将圆盘从A柱移到C柱,且排列顺序不变) 思想:不管A柱有多少个圆盘(假设n个),我们可以将看成将上面的(n-1)个圆盘看成一个整体,那么问题就变得非常简单: 1)将上面的(n-1)个圆盘实现从A柱全部移动到B柱 2)把最后一个圆盘从A柱移到C柱 3)将刚刚移到B柱的(n-1)个圆盘从B柱全部移动到C柱。 这就是整个的过程,那么我们可以看到,上述1)和3)其实也是一次汉诺塔的完整过程,只不过是圆盘数目不同。因此,这里利用递归函数就能快速简单地解决问题。 代码如下; def move(n,a,b,c): ''' n:圆盘数 a,b,c分别代表三个柱子 ''' if n == 1: print(a, '-->', c) else: move(n-1,a,c,b) print(a, '-->', c) move(n-1,b,a,c) if __name__ == '__main__': move(3,'A','B','C') # 输出: # A --> C # A --> B # C --> B # A --> C # B --> A # B --> C # A

汉诺塔问题(1)

此生再无相见时 提交于 2019-11-28 02:10:02
View Code //************************************************** Description 问题的提出:约19世纪末,在欧州的商店中出售一种智力玩具,在一块铜板上有三根杆(分别使A、B、C),最左边的杆上自上而下、 由小到大顺序串着由64个圆盘构成的塔。目的是将最左边杆上的盘全部移到右边的杆上,条件是一次只能移动一个盘,且不允许大盘 放在小盘的上面。这是一个著名的问题,几乎所有的教材上都有这个问题。由于条件是一次只能移动一个盘,且不允许大盘放在小盘 上面,所以64个盘的移动次数是:18446744073709551615 这是一个天文数字,若每一微秒可能计算(并不输出)一次移动,那么也需要几乎一百万年。我们仅能找出问题的解决方法并解决较小 N值时的汉诺塔,但很难用计算机解决64层的汉诺塔。 Input 测试数据有多组,每组此时数据就包含一个要移动的盘数n,为了使题目简单话,则n<=10。输入0表示结束。 Output 输出每组移动的步骤,并每十步换一行,格式如样例输出。并且每组之间空一行,但最后一组例外。 Sample Input : 3 Sample Output: A-->C A-->B C-->B A-->C B-->A B-->C A-->C //***********************************

Python案例:汉诺塔游戏

旧时模样 提交于 2019-11-27 23:06:25
Python案例:汉诺塔游戏 游戏规则: (1)一次只能移动一个环 (2)小环必须在大环之上 (3)所有环从A柱移到C柱 1、编写程序hanoi.py STEP = 0 def move(p1, p2): global STEP STEP = STEP + 1 print('Step ' + str(STEP) + ': ', p1, '->', p2) def hanoi(n, x, y, z): if n == 1: move(x, z) else: hanoi(n-1, x, z, y) move(x, z) hanoi(n-1, y, x, z) hanoi(3, 'A', 'B', 'C') 2、运行程序,查看结果 来源: CSDN 作者: howard2005 链接: https://blog.csdn.net/howard2005/article/details/79446646

数据结构之汉诺塔问题

|▌冷眼眸甩不掉的悲伤 提交于 2019-11-27 16:51:31
  汉诺塔:汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根 金刚石 柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。 ——摘自百度百科 汉诺塔之三个盘子,需要几步 汉诺塔之四个盘子,需要几步? 汉诺塔之二十个盘子,需要几步? 来源: https://www.cnblogs.com/l-x-x-y-d-j/p/11370810.html

程序员成长之旅——函数与递归经典题目

◇◆丶佛笑我妖孽 提交于 2019-11-27 16:19:05
程序员成长之旅——函数与递归经典题目 汉诺塔问题 青蛙跳台阶问题 汉诺塔问题 汉诺塔是什么,这个不多加说明可以看这个 https://baike.baidu.com/item/%E6%B1%89%E8%AF%BA%E5%A1%94/3468295?fr=aladdin 那如何用递归思想实现汉诺塔问题呢? 假设看四层 把A中n-1层看成一个整体,将它经过一系列操作到B上,然后将A移动到C上,在将B中n-1层看成一个整体,经过一系列操作到C上。这样就完成了汉诺塔问题。 # define _CRT_SECURE_NO_WARNINGS 1 # include <stdio.h> int t = 0 ; void hanoi ( int n , char a , char b , char c ) { if ( n == 1 ) { printf ( "%c->%c\n" , a , c ) ; t ++ ; } else { h ( n - 1 , a , c , b ) ; printf ( "%c->%c\n" , a , c ) ; t ++ ; h ( n - 1 , b , a , c ) ; } } int main ( ) { int x = 0 ; printf ( "输入汉诺塔的层数:>" ) ; scanf ( "%d" , & x ) ; hanoi ( x ,